detached 20325a8

Remove unwanted files

commit
20325a8e8928343e435dabc6c89dc2cdb8446d1a
author
bnema · · 2023-09-16 06:20 UTC
parent
d6faee0
signature
unsigned
6 files · +0 -2596

this diff holds invisible characters (direction controls, zero-width characters). They are shown as <U+XXXX> markers, never applied.

A internal/gotemplate/models/html/login/index.gohtml +0 -0

no textual change.

D s="flex flex-col md:flex-row justify-items-center w-full"> +0 -404
@@ -1,404 +0,0 @@
1-<U+001B>[1mdiff --git a/changes.txt b/changes.txt<U+001B>[m
2-<U+001B>[1mdeleted file mode 100644<U+001B>[m
3-<U+001B>[1mindex ab78b90..0000000<U+001B>[m
4-<U+001B>[1m--- a/changes.txt<U+001B>[m
5-<U+001B>[1m+++ /dev/null<U+001B>[m
6-<U+001B>[36m@@ -1,326 +0,0 @@<U+001B>[m
7-<U+001B>[31m-diff --git a/:memory b/:memory<U+001B>[m
8-<U+001B>[31m-new file mode 100644<U+001B>[m
9-<U+001B>[31m-index 0000000..9760229<U+001B>[m
10-<U+001B>[31m-Binary files /dev/null and b/:memory differ<U+001B>[m
11-<U+001B>[31m-diff --git a/cmd/main.go b/cmd/main.go<U+001B>[m
12-<U+001B>[31m-index 6a95d32..b8e2cd4 100644<U+001B>[m
13-<U+001B>[31m---- a/cmd/main.go<U+001B>[m
14-<U+001B>[31m-+++ b/cmd/main.go<U+001B>[m
15-<U+001B>[31m-@@ -4,17 +4,30 @@ import (<U+001B>[m
16-<U+001B>[31m- "fmt"<U+001B>[m
17-<U+001B>[31m- "log/slog"<U+001B>[m
18-<U+001B>[31m- <U+001B>[m
19-<U+001B>[31m-+ "github.com/labstack/echo/v4"<U+001B>[m
20-<U+001B>[31m-+<U+001B>[m
21-<U+001B>[31m- "github.com/bnema/gordon/internal/app"<U+001B>[m
22-<U+001B>[31m- "github.com/bnema/gordon/internal/httpserve"<U+001B>[m
23-<U+001B>[31m-- "github.com/labstack/echo/v4"<U+001B>[m
24-<U+001B>[31m- )<U+001B>[m
25-<U+001B>[31m- <U+001B>[m
26-<U+001B>[31m- func main() {<U+001B>[m
27-<U+001B>[31m- a := app.NewApp()<U+001B>[m
28-<U+001B>[31m-+<U+001B>[m
29-<U+001B>[31m-+ // Initialize database<U+001B>[m
30-<U+001B>[31m-+ db, err := app.InitializeDB(a)<U+001B>[m
31-<U+001B>[31m-+ if err != nil {<U+001B>[m
32-<U+001B>[31m-+ slog.Error("Failed to load database", err)<U+001B>[m
33-<U+001B>[31m-+ } else {<U+001B>[m
34-<U+001B>[31m-+ slog.Info("Database loaded")<U+001B>[m
35-<U+001B>[31m-+ }<U+001B>[m
36-<U+001B>[31m-+<U+001B>[m
37-<U+001B>[31m-+ fmt.Println(db)<U+001B>[m
38-<U+001B>[31m-+<U+001B>[m
39-<U+001B>[31m- e := echo.New()<U+001B>[m
40-<U+001B>[31m- e.HideBanner = true<U+001B>[m
41-<U+001B>[31m- e.HidePort = true<U+001B>[m
42-<U+001B>[31m- e = httpserve.RegisterRoutes(e, a)<U+001B>[m
43-<U+001B>[31m- slog.Info("Starting server", "port", a.HttpPort)<U+001B>[m
44-<U+001B>[31m- slog.Error("Server error", e.Start(fmt.Sprintf(":%d", a.HttpPort)))<U+001B>[m
45-<U+001B>[31m-+<U+001B>[m
46-<U+001B>[31m- }<U+001B>[m
47-<U+001B>[31m-diff --git a/go.mod b/go.mod<U+001B>[m
48-<U+001B>[31m-index 35e2d3c..8a3ac59 100644<U+001B>[m
49-<U+001B>[31m---- a/go.mod<U+001B>[m
50-<U+001B>[31m-+++ b/go.mod<U+001B>[m
51-<U+001B>[31m-@@ -24,6 +24,7 @@ require (<U+001B>[m
52-<U+001B>[31m- github.com/gorilla/securecookie v1.1.1 // indirect<U+001B>[m
53-<U+001B>[31m- github.com/gorilla/sessions v1.2.1 // indirect<U+001B>[m
54-<U+001B>[31m- github.com/klauspost/compress v1.16.7 // indirect<U+001B>[m
55-<U+001B>[31m-+ github.com/kr/text v0.1.0 // indirect<U+001B>[m
56-<U+001B>[31m- github.com/labstack/gommon v0.4.0 // indirect<U+001B>[m
57-<U+001B>[31m- github.com/mattn/go-colorable v0.1.13 // indirect<U+001B>[m
58-<U+001B>[31m- github.com/mattn/go-isatty v0.0.19 // indirect<U+001B>[m
59-<U+001B>[31m-@@ -35,6 +36,7 @@ require (<U+001B>[m
60-<U+001B>[31m- github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect<U+001B>[m
61-<U+001B>[31m- github.com/opencontainers/runc v1.1.9 // indirect<U+001B>[m
62-<U+001B>[31m- github.com/pkg/errors v0.9.1 // indirect<U+001B>[m
63-<U+001B>[31m-+ github.com/rogpeppe/go-internal v1.11.0 // indirect<U+001B>[m
64-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3 // indirect<U+001B>[m
65-<U+001B>[31m- github.com/valyala/bytebufferpool v1.0.0 // indirect<U+001B>[m
66-<U+001B>[31m- github.com/valyala/fasttemplate v1.2.2 // indirect<U+001B>[m
67-<U+001B>[31m-@@ -45,5 +47,6 @@ require (<U+001B>[m
68-<U+001B>[31m- golang.org/x/text v0.11.0 // indirect<U+001B>[m
69-<U+001B>[31m- golang.org/x/time v0.3.0 // indirect<U+001B>[m
70-<U+001B>[31m- golang.org/x/tools v0.7.0 // indirect<U+001B>[m
71-<U+001B>[31m-+ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect<U+001B>[m
72-<U+001B>[31m- gotest.tools/v3 v3.5.0 // indirect<U+001B>[m
73-<U+001B>[31m- )<U+001B>[m
74-<U+001B>[31m-diff --git a/go.sum b/go.sum<U+001B>[m
75-<U+001B>[31m-index 7b9b857..17b0bcd 100644<U+001B>[m
76-<U+001B>[31m---- a/go.sum<U+001B>[m
77-<U+001B>[31m-+++ b/go.sum<U+001B>[m
78-<U+001B>[31m-@@ -39,6 +39,11 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI<U+001B>[m
79-<U+001B>[31m- github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=<U+001B>[m
80-<U+001B>[31m- github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=<U+001B>[m
81-<U+001B>[31m- github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=<U+001B>[m
82-<U+001B>[31m-+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=<U+001B>[m
83-<U+001B>[31m-+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=<U+001B>[m
84-<U+001B>[31m-+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=<U+001B>[m
85-<U+001B>[31m-+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=<U+001B>[m
86-<U+001B>[31m-+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=<U+001B>[m
87-<U+001B>[31m- github.com/labstack/echo-contrib v0.15.0 h1:9K+oRU265y4Mu9zpRDv3X+DGTqUALY6oRHCSZZKCRVU=<U+001B>[m
88-<U+001B>[31m- github.com/labstack/echo-contrib v0.15.0/go.mod h1:lei+qt5CLB4oa7VHTE0yEfQSEB9XTJI1LUqko9UWvo4=<U+001B>[m
89-<U+001B>[31m- github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4=<U+001B>[m
90-<U+001B>[31m-@@ -72,6 +77,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=<U+001B>[m
91-<U+001B>[31m- github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=<U+001B>[m
92-<U+001B>[31m- github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=<U+001B>[m
93-<U+001B>[31m- github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=<U+001B>[m
94-<U+001B>[31m-+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=<U+001B>[m
95-<U+001B>[31m-+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=<U+001B>[m
96-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=<U+001B>[m
97-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=<U+001B>[m
98-<U+001B>[31m- github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=<U+001B>[m
99-<U+001B>[31m-@@ -153,8 +160,9 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T<U+001B>[m
100-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
101-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
102-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
103-<U+001B>[31m--gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=<U+001B>[m
104-<U+001B>[31m- gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=<U+001B>[m
105-<U+001B>[31m-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=<U+001B>[m
106-<U+001B>[31m-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=<U+001B>[m
107-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=<U+001B>[m
108-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=<U+001B>[m
109-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=<U+001B>[m
110-<U+001B>[31m-diff --git a/internal/app/app.go b/internal/app/app.go<U+001B>[m
111-<U+001B>[31m-index c6f49ac..1dd44b8 100644<U+001B>[m
112-<U+001B>[31m---- a/internal/app/app.go<U+001B>[m
113-<U+001B>[31m-+++ b/internal/app/app.go<U+001B>[m
114-<U+001B>[31m-@@ -27,6 +27,7 @@ const (<U+001B>[m
115-<U+001B>[31m- type App struct {<U+001B>[m
116-<U+001B>[31m- TemplateFS fs.FS<U+001B>[m
117-<U+001B>[31m- PublicFS fs.FS<U+001B>[m
118-<U+001B>[31m-+ DB interface{}<U+001B>[m
119-<U+001B>[31m- BuildVersion string<U+001B>[m
120-<U+001B>[31m- BuildDir string<U+001B>[m
121-<U+001B>[31m- DBDir string<U+001B>[m
122-<U+001B>[31m-diff --git a/internal/app/sqlite.go b/internal/app/sqlite.go<U+001B>[m
123-<U+001B>[31m-index 9f1b1ab..ddc6a1e 100644<U+001B>[m
124-<U+001B>[31m---- a/internal/app/sqlite.go<U+001B>[m
125-<U+001B>[31m-+++ b/internal/app/sqlite.go<U+001B>[m
126-<U+001B>[31m-@@ -5,58 +5,78 @@ import (<U+001B>[m
127-<U+001B>[31m- "database/sql"<U+001B>[m
128-<U+001B>[31m- "fmt"<U+001B>[m
129-<U+001B>[31m- "os"<U+001B>[m
130-<U+001B>[31m-+ "path/filepath"<U+001B>[m
131-<U+001B>[31m- <U+001B>[m
132-<U+001B>[31m-- sqlite3 "github.com/mattn/go-sqlite3"<U+001B>[m
133-<U+001B>[31m-+ "github.com/bnema/gordon/internal/database/migrate"<U+001B>[m
134-<U+001B>[31m-+ "github.com/mattn/go-sqlite3"<U+001B>[m
135-<U+001B>[31m- )<U+001B>[m
136-<U+001B>[31m- <U+001B>[m
137-<U+001B>[31m--// Initialize in-memory SQLite database and returns its connection<U+001B>[m
138-<U+001B>[31m--func InitDB() (db *sql.DB, err error) {<U+001B>[m
139-<U+001B>[31m-- db, err = sql.Open("sqlite3", "file::memory?cache=shared")<U+001B>[m
140-<U+001B>[31m-- if err != nil {<U+001B>[m
141-<U+001B>[31m-- return nil, fmt.Errorf("failed to open in-memory database: %v", err)<U+001B>[m
142-<U+001B>[31m-- }<U+001B>[m
143-<U+001B>[31m-- return<U+001B>[m
144-<U+001B>[31m--}<U+001B>[m
145-<U+001B>[31m--<U+001B>[m
146-<U+001B>[31m--// CloseDB closes the database connection and backs up the in-memory database to disk<U+001B>[m
147-<U+001B>[31m--func CloseDB(db *sql.DB, a *App) error {<U+001B>[m
148-<U+001B>[31m-- if err := BackupDB(db, a); err != nil {<U+001B>[m
149-<U+001B>[31m-- return err<U+001B>[m
150-<U+001B>[31m-- }<U+001B>[m
151-<U+001B>[31m-+// InitializeDB initializes the SQLite database. If a database file exists on disk, it loads it into memory.<U+001B>[m
152-<U+001B>[31m-+// Otherwise, it creates a new in-memory database and bootstraps it.<U+001B>[m
153-<U+001B>[31m-+func InitializeDB(a *App) (*sql.DB, error) {<U+001B>[m
154-<U+001B>[31m-+ dbfp := a.GetDBFilePath()<U+001B>[m
155-<U+001B>[31m- <U+001B>[m
156-<U+001B>[31m-- if err := db.Close(); err != nil {<U+001B>[m
157-<U+001B>[31m-- return fmt.Errorf("failed to close database: %v", err)<U+001B>[m
158-<U+001B>[31m-+ // Check if the directory exists, if not create it<U+001B>[m
159-<U+001B>[31m-+ dir := filepath.Dir(a.DBDir)<U+001B>[m
160-<U+001B>[31m-+ fmt.Println("dir", dir)<U+001B>[m
161-<U+001B>[31m-+ if _, err := os.Stat(dir); os.IsNotExist(err) {<U+001B>[m
162-<U+001B>[31m-+ err = os.MkdirAll(dir, 0755)<U+001B>[m
163-<U+001B>[31m-+ if err != nil {<U+001B>[m
164-<U+001B>[31m-+ return nil, fmt.Errorf("failed to create directory: %v", err)<U+001B>[m
165-<U+001B>[31m-+ }<U+001B>[m
166-<U+001B>[31m- }<U+001B>[m
167-<U+001B>[31m- <U+001B>[m
168-<U+001B>[31m-- return nil<U+001B>[m
169-<U+001B>[31m--}<U+001B>[m
170-<U+001B>[31m-+ // If the database file doesn't exist on disk<U+001B>[m
171-<U+001B>[31m-+ if _, err := os.Stat(dbfp); os.IsNotExist(err) {<U+001B>[m
172-<U+001B>[31m-+ memDB, err := initInMemoryDB()<U+001B>[m
173-<U+001B>[31m-+ if err != nil {<U+001B>[m
174-<U+001B>[31m-+ return nil, err<U+001B>[m
175-<U+001B>[31m-+ }<U+001B>[m
176-<U+001B>[31m- <U+001B>[m
177-<U+001B>[31m--// LoadDBIntoMemory loads the database from disk into memory<U+001B>[m
178-<U+001B>[31m--func LoadDBIntoMemory(a *App) (*sql.DB, error) {<U+001B>[m
179-<U+001B>[31m-- dbfp := a.GetDBFilePath()<U+001B>[m
180-<U+001B>[31m-+ // Run the bootstrap<U+001B>[m
181-<U+001B>[31m-+ RunBootstrap(memDB)<U+001B>[m
182-<U+001B>[31m- <U+001B>[m
183-<U+001B>[31m-- if _, err := os.Stat(dbfp); err != nil {<U+001B>[m
184-<U+001B>[31m-- return nil, nil<U+001B>[m
185-<U+001B>[31m-+ // Explicitly backup the in-memory database to disk<U+001B>[m
186-<U+001B>[31m-+ err = BackupDB(memDB, a)<U+001B>[m
187-<U+001B>[31m-+ if err != nil {<U+001B>[m
188-<U+001B>[31m-+ return nil, fmt.Errorf("failed to backup in-memory database to disk: %v", err)<U+001B>[m
189-<U+001B>[31m-+ }<U+001B>[m
190-<U+001B>[31m- }<U+001B>[m
191-<U+001B>[31m- <U+001B>[m
192-<U+001B>[31m-- memDB, err := InitDB()<U+001B>[m
193-<U+001B>[31m-+ memDB, err := initInMemoryDB()<U+001B>[m
194-<U+001B>[31m- if err != nil {<U+001B>[m
195-<U+001B>[31m- return nil, err<U+001B>[m
196-<U+001B>[31m- }<U+001B>[m
197-<U+001B>[31m--<U+001B>[m
198-<U+001B>[31m- diskDB, err := sql.Open("sqlite3", dbfp)<U+001B>[m
199-<U+001B>[31m- if err != nil {<U+001B>[m
200-<U+001B>[31m- return nil, fmt.Errorf("failed to open database file: %v", err)<U+001B>[m
201-<U+001B>[31m- }<U+001B>[m
202-<U+001B>[31m-+ defer diskDB.Close()<U+001B>[m
203-<U+001B>[31m- <U+001B>[m
204-<U+001B>[31m- if err := transferData(diskDB, memDB); err != nil {<U+001B>[m
205-<U+001B>[31m- return nil, err<U+001B>[m
206-<U+001B>[31m- }<U+001B>[m
207-<U+001B>[31m--<U+001B>[m
208-<U+001B>[31m- return memDB, nil<U+001B>[m
209-<U+001B>[31m- }<U+001B>[m
210-<U+001B>[31m- <U+001B>[m
211-<U+001B>[31m--// transferData transfers data from srcDB to dstDB<U+001B>[m
212-<U+001B>[31m-+func initInMemoryDB() (*sql.DB, error) {<U+001B>[m
213-<U+001B>[31m-+ db, err := sql.Open("sqlite3", "file::memory?cache=shared")<U+001B>[m
214-<U+001B>[31m-+ if err != nil {<U+001B>[m
215-<U+001B>[31m-+ return nil, fmt.Errorf("failed to open in-memory database: %v", err)<U+001B>[m
216-<U+001B>[31m-+ }<U+001B>[m
217-<U+001B>[31m-+ return db, nil<U+001B>[m
218-<U+001B>[31m-+}<U+001B>[m
219-<U+001B>[31m-+<U+001B>[m
220-<U+001B>[31m-+func CloseAndBackupDB(db *sql.DB, a *App) error {<U+001B>[m
221-<U+001B>[31m-+ if err := BackupDB(db, a); err != nil {<U+001B>[m
222-<U+001B>[31m-+ return err<U+001B>[m
223-<U+001B>[31m-+ }<U+001B>[m
224-<U+001B>[31m-+ if err := db.Close(); err != nil {<U+001B>[m
225-<U+001B>[31m-+ return fmt.Errorf("failed to close database: %v", err)<U+001B>[m
226-<U+001B>[31m-+ }<U+001B>[m
227-<U+001B>[31m-+ return nil<U+001B>[m
228-<U+001B>[31m-+}<U+001B>[m
229-<U+001B>[31m-+<U+001B>[m
230-<U+001B>[31m- func transferData(srcDB, dstDB *sql.DB) error {<U+001B>[m
231-<U+001B>[31m- srcConn, err := srcDB.Conn(context.Background())<U+001B>[m
232-<U+001B>[31m- if err != nil {<U+001B>[m
233-<U+001B>[31m-@@ -74,35 +94,50 @@ func transferData(srcDB, dstDB *sql.DB) error {<U+001B>[m
234-<U+001B>[31m- return dstConn.Raw(func(dstRawConn interface{}) error {<U+001B>[m
235-<U+001B>[31m- srcSqlite3Conn := srcRawConn.(*sqlite3.SQLiteConn)<U+001B>[m
236-<U+001B>[31m- dstSqlite3Conn := dstRawConn.(*sqlite3.SQLiteConn)<U+001B>[m
237-<U+001B>[31m--<U+001B>[m
238-<U+001B>[31m- _, err := srcSqlite3Conn.Backup("main", dstSqlite3Conn, "main")<U+001B>[m
239-<U+001B>[31m- return err<U+001B>[m
240-<U+001B>[31m- })<U+001B>[m
241-<U+001B>[31m- })<U+001B>[m
242-<U+001B>[31m- }<U+001B>[m
243-<U+001B>[31m- <U+001B>[m
244-<U+001B>[31m--// BackupDB backs up the in-memory database to disk<U+001B>[m
245-<U+001B>[31m- func BackupDB(db *sql.DB, a *App) error {<U+001B>[m
246-<U+001B>[31m- dbfp := a.GetDBFilePath()<U+001B>[m
247-<U+001B>[31m--<U+001B>[m
248-<U+001B>[31m- conn, err := db.Conn(context.Background())<U+001B>[m
249-<U+001B>[31m- if err != nil {<U+001B>[m
250-<U+001B>[31m- return fmt.Errorf("failed to get underlying database connection: %v", err)<U+001B>[m
251-<U+001B>[31m- }<U+001B>[m
252-<U+001B>[31m-+ defer conn.Close()<U+001B>[m
253-<U+001B>[31m- <U+001B>[m
254-<U+001B>[31m- return conn.Raw(func(sqliteConn interface{}) error {<U+001B>[m
255-<U+001B>[31m- sqlite3Conn := sqliteConn.(*sqlite3.SQLiteConn)<U+001B>[m
256-<U+001B>[31m-- backupDB, err := sqlite3Conn.Backup(dbfp, sqlite3Conn, "main")<U+001B>[m
257-<U+001B>[31m-+ diskDB, err := sql.Open("sqlite3", dbfp)<U+001B>[m
258-<U+001B>[31m-+ fmt.Println("diskDB", diskDB)<U+001B>[m
259-<U+001B>[31m-+ if err != nil {<U+001B>[m
260-<U+001B>[31m-+ return fmt.Errorf("failed to open destination database file: %v", err)<U+001B>[m
261-<U+001B>[31m-+ }<U+001B>[m
262-<U+001B>[31m-+ defer diskDB.Close()<U+001B>[m
263-<U+001B>[31m-+<U+001B>[m
264-<U+001B>[31m-+ diskConn, err := diskDB.Conn(context.Background())<U+001B>[m
265-<U+001B>[31m- if err != nil {<U+001B>[m
266-<U+001B>[31m-- return fmt.Errorf("failed to create backup: %v", err)<U+001B>[m
267-<U+001B>[31m-+ return fmt.Errorf("failed to get connection from diskDB: %v", err)<U+001B>[m
268-<U+001B>[31m- }<U+001B>[m
269-<U+001B>[31m-+ defer diskConn.Close()<U+001B>[m
270-<U+001B>[31m-+<U+001B>[m
271-<U+001B>[31m-+ var backupDB *sqlite3.SQLiteBackup<U+001B>[m
272-<U+001B>[31m-+ err = diskConn.Raw(func(diskRawConn interface{}) error {<U+001B>[m
273-<U+001B>[31m-+ backupDB, err = sqlite3Conn.Backup("main", diskRawConn.(*sqlite3.SQLiteConn), "main")<U+001B>[m
274-<U+001B>[31m-+ return err<U+001B>[m
275-<U+001B>[31m-+ })<U+001B>[m
276-<U+001B>[31m- defer backupDB.Close()<U+001B>[m
277-<U+001B>[31m- <U+001B>[m
278-<U+001B>[31m- _, err = backupDB.Step(-1)<U+001B>[m
279-<U+001B>[31m- if err != nil {<U+001B>[m
280-<U+001B>[31m- return fmt.Errorf("failed to backup in-memory database: %v", err)<U+001B>[m
281-<U+001B>[31m- }<U+001B>[m
282-<U+001B>[31m--<U+001B>[m
283-<U+001B>[31m- return nil<U+001B>[m
284-<U+001B>[31m- })<U+001B>[m
285-<U+001B>[31m- }<U+001B>[m
286-<U+001B>[31m-+<U+001B>[m
287-<U+001B>[31m-+func RunBootstrap(db *sql.DB) error {<U+001B>[m
288-<U+001B>[31m-+ return migrate.CreateUserTable(db)<U+001B>[m
289-<U+001B>[31m-+}<U+001B>[m
290-<U+001B>[31m-diff --git a/internal/database/migrate/bootstrapdb.go b/internal/database/migrate/bootstrapdb.go<U+001B>[m
291-<U+001B>[31m-new file mode 100644<U+001B>[m
292-<U+001B>[31m-index 0000000..1f53246<U+001B>[m
293-<U+001B>[31m---- /dev/null<U+001B>[m
294-<U+001B>[31m-+++ b/internal/database/migrate/bootstrapdb.go<U+001B>[m
295-<U+001B>[31m-@@ -0,0 +1,24 @@<U+001B>[m
296-<U+001B>[31m-+package migrate<U+001B>[m
297-<U+001B>[31m-+<U+001B>[m
298-<U+001B>[31m-+import (<U+001B>[m
299-<U+001B>[31m-+ "database/sql"<U+001B>[m
300-<U+001B>[31m-+ "fmt"<U+001B>[m
301-<U+001B>[31m-+)<U+001B>[m
302-<U+001B>[31m-+<U+001B>[m
303-<U+001B>[31m-+// createUserTable creates the 'user' table in the provided SQLite database.<U+001B>[m
304-<U+001B>[31m-+func CreateUserTable(db *sql.DB) error {<U+001B>[m
305-<U+001B>[31m-+ createTableSQL := `<U+001B>[m
306-<U+001B>[31m-+ CREATE TABLE user (<U+001B>[m
307-<U+001B>[31m-+ id INTEGER PRIMARY KEY AUTOINCREMENT,<U+001B>[m
308-<U+001B>[31m-+ username TEXT NOT NULL,<U+001B>[m
309-<U+001B>[31m-+ password TEXT NOT NULL, -- This should be hashed and salted in a real-world scenario.<U+001B>[m
310-<U+001B>[31m-+ oauth_token TEXT<U+001B>[m
311-<U+001B>[31m-+ );`<U+001B>[m
312-<U+001B>[31m-+<U+001B>[m
313-<U+001B>[31m-+ _, err := db.Exec(createTableSQL)<U+001B>[m
314-<U+001B>[31m-+ if err != nil {<U+001B>[m
315-<U+001B>[31m-+ return fmt.Errorf("failed to create user table: %v", err)<U+001B>[m
316-<U+001B>[31m-+ }<U+001B>[m
317-<U+001B>[31m-+<U+001B>[m
318-<U+001B>[31m-+ return nil<U+001B>[m
319-<U+001B>[31m-+}<U+001B>[m
320-<U+001B>[31m-diff --git a/internal/httpserve/handler/adminroutes.go b/internal/httpserve/handler/adminroutes.go<U+001B>[m
321-<U+001B>[31m-index 8701ae3..f4acd64 100644<U+001B>[m
322-<U+001B>[31m---- a/internal/httpserve/handler/adminroutes.go<U+001B>[m
323-<U+001B>[31m-+++ b/internal/httpserve/handler/adminroutes.go<U+001B>[m
324-<U+001B>[31m-@@ -1,8 +1,6 @@<U+001B>[m
325-<U+001B>[31m- package handler<U+001B>[m
326-<U+001B>[31m- <U+001B>[m
327-<U+001B>[31m- import (<U+001B>[m
328-<U+001B>[31m-- "fmt"<U+001B>[m
329-<U+001B>[31m--<U+001B>[m
330-<U+001B>[31m- "github.com/bnema/gordon/internal/app"<U+001B>[m
331-<U+001B>[31m- "github.com/bnema/gordon/internal/gotemplate/render"<U+001B>[m
332-<U+001B>[31m- "github.com/bnema/gordon/internal/httpserve/middleware"<U+001B>[m
333-<U+001B>[1mdiff --git a/internal/httpserve/handler/oauth.go b/internal/httpserve/handler/oauth.go<U+001B>[m
334-<U+001B>[1mindex bd40379..b876c75 100644<U+001B>[m
335-<U+001B>[1m--- a/internal/httpserve/handler/oauth.go<U+001B>[m
336-<U+001B>[1m+++ b/internal/httpserve/handler/oauth.go<U+001B>[m
337-<U+001B>[36m@@ -12,6 +12,7 @@<U+001B>[m <U+001B>[mimport (<U+001B>[m
338- "github.com/markbates/goth/gothic"<U+001B>[m
339- "github.com/markbates/goth/providers/github"<U+001B>[m
340- "net/http"<U+001B>[m
341-<U+001B>[32m+<U+001B>[m <U+001B>[32m"os"<U+001B>[m
342- )<U+001B>[m
343- <U+001B>[m
344- var providerNames []string<U+001B>[m
345-<U+001B>[1mdiff --git a/internal/httpserve/router.go b/internal/httpserve/router.go<U+001B>[m
346-<U+001B>[1mindex bc1368c..edd2748 100644<U+001B>[m
347-<U+001B>[1m--- a/internal/httpserve/router.go<U+001B>[m
348-<U+001B>[1m+++ b/internal/httpserve/router.go<U+001B>[m
349-<U+001B>[36m@@ -19,34 +19,19 @@<U+001B>[m <U+001B>[mfunc RegisterRoutes(e *echo.Echo, a *app.App) *echo.Echo {<U+001B>[m
350- // Use session middleware<U+001B>[m
351- // Add session middleware<U+001B>[m
352- e.Use(session.Middleware(sessions.NewCookieStore([]byte(os.Getenv("SECRET")))))<U+001B>[m
353-<U+001B>[31m- // e.Use(middleware.SecureRoutes())<U+001B>[m
354- e.Use(middleware.ColorSchemeDetection)<U+001B>[m
355- e.Use(middleware.LanguageDetection)<U+001B>[m
356- <U+001B>[m
357- // Register routes<U+001B>[m
358-<U+001B>[31m-<U+001B>[m
359-<U+001B>[31m- // Serve admin routes<U+001B>[m
360- bindAdminRoute(e, a, AdminPath)<U+001B>[m
361-<U+001B>[31m- // Serve static files<U+001B>[m
362- bindStaticRoute(e, a, "/*")<U+001B>[m
363-<U+001B>[32m+<U+001B>[m <U+001B>[32mbindLoginRoute(e, a, AdminPath)<U+001B>[m
364-<U+001B>[32m+<U+001B>[m
365- // Protect the root path with a 403<U+001B>[m
366- e.GET("/", func(c echo.Context) error {<U+001B>[m
367- return c.String(403, "403 Forbidden")<U+001B>[m
368- })<U+001B>[m
369- <U+001B>[m
370-<U+001B>[31m- e.GET(a.AdminPath+"/login", func(c echo.Context) error {<U+001B>[m
371-<U+001B>[31m- return handler.RenderLoginPage(c, a)<U+001B>[m
372-<U+001B>[31m- })<U+001B>[m
373-<U+001B>[31m- e.GET(a.AdminPath+"/login/:provider", func(c echo.Context) error {<U+001B>[m
374-<U+001B>[31m- return handler.StartOAuth(c, a)<U+001B>[m
375-<U+001B>[31m- })<U+001B>[m
376-<U+001B>[31m- e.GET(a.OauthCallbackURL, func(c echo.Context) error {<U+001B>[m
377-<U+001B>[31m- return handler.OAuthCallback(c, a)<U+001B>[m
378-<U+001B>[31m- })<U+001B>[m
379-<U+001B>[31m- e.GET(a.AdminPath+"/logout", func(c echo.Context) error {<U+001B>[m
380-<U+001B>[31m- return handler.Logout(c, a)<U+001B>[m
381-<U+001B>[31m- })<U+001B>[m
382-<U+001B>[31m-<U+001B>[m
383- return e<U+001B>[m
384- }<U+001B>[m
385- <U+001B>[m
386-<U+001B>[36m@@ -61,3 +46,18 @@<U+001B>[m <U+001B>[mfunc bindAdminRoute(e *echo.Echo, a *app.App, path string) {<U+001B>[m
387- return handler.AdminRoute(c, a)<U+001B>[m
388- })<U+001B>[m
389- }<U+001B>[m
390-<U+001B>[32m+<U+001B>[m
391-<U+001B>[32m+<U+001B>[m<U+001B>[32mfunc bindLoginRoute(e *echo.Echo, a *app.App, adminPath string) {<U+001B>[m
392-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/login", func(c echo.Context) error {<U+001B>[m
393-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.RenderLoginPage(c, a)<U+001B>[m
394-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
395-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/login/:provider", func(c echo.Context) error {<U+001B>[m
396-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.StartOAuth(c, a)<U+001B>[m
397-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
398-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(a.OauthCallbackURL, func(c echo.Context) error {<U+001B>[m
399-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.OAuthCallback(c, a)<U+001B>[m
400-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
401-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/logout", func(c echo.Context) error {<U+001B>[m
402-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.Logout(c, a)<U+001B>[m
403-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
404-<U+001B>[32m+<U+001B>[m<U+001B>[32m}<U+001B>[m
@@ -1,404 +0,0 @@
1-<U+001B>[1mdiff --git a/changes.txt b/changes.txt<U+001B>[m
2-<U+001B>[1mdeleted file mode 100644<U+001B>[m
3-<U+001B>[1mindex ab78b90..0000000<U+001B>[m
4-<U+001B>[1m--- a/changes.txt<U+001B>[m
5-<U+001B>[1m+++ /dev/null<U+001B>[m
6-<U+001B>[36m@@ -1,326 +0,0 @@<U+001B>[m
7-<U+001B>[31m-diff --git a/:memory b/:memory<U+001B>[m
8-<U+001B>[31m-new file mode 100644<U+001B>[m
9-<U+001B>[31m-index 0000000..9760229<U+001B>[m
10-<U+001B>[31m-Binary files /dev/null and b/:memory differ<U+001B>[m
11-<U+001B>[31m-diff --git a/cmd/main.go b/cmd/main.go<U+001B>[m
12-<U+001B>[31m-index 6a95d32..b8e2cd4 100644<U+001B>[m
13-<U+001B>[31m---- a/cmd/main.go<U+001B>[m
14-<U+001B>[31m-+++ b/cmd/main.go<U+001B>[m
15-<U+001B>[31m-@@ -4,17 +4,30 @@ import (<U+001B>[m
16-<U+001B>[31m- "fmt"<U+001B>[m
17-<U+001B>[31m- "log/slog"<U+001B>[m
18-<U+001B>[31m- <U+001B>[m
19-<U+001B>[31m-+ "github.com/labstack/echo/v4"<U+001B>[m
20-<U+001B>[31m-+<U+001B>[m
21-<U+001B>[31m- "github.com/bnema/gordon/internal/app"<U+001B>[m
22-<U+001B>[31m- "github.com/bnema/gordon/internal/httpserve"<U+001B>[m
23-<U+001B>[31m-- "github.com/labstack/echo/v4"<U+001B>[m
24-<U+001B>[31m- )<U+001B>[m
25-<U+001B>[31m- <U+001B>[m
26-<U+001B>[31m- func main() {<U+001B>[m
27-<U+001B>[31m- a := app.NewApp()<U+001B>[m
28-<U+001B>[31m-+<U+001B>[m
29-<U+001B>[31m-+ // Initialize database<U+001B>[m
30-<U+001B>[31m-+ db, err := app.InitializeDB(a)<U+001B>[m
31-<U+001B>[31m-+ if err != nil {<U+001B>[m
32-<U+001B>[31m-+ slog.Error("Failed to load database", err)<U+001B>[m
33-<U+001B>[31m-+ } else {<U+001B>[m
34-<U+001B>[31m-+ slog.Info("Database loaded")<U+001B>[m
35-<U+001B>[31m-+ }<U+001B>[m
36-<U+001B>[31m-+<U+001B>[m
37-<U+001B>[31m-+ fmt.Println(db)<U+001B>[m
38-<U+001B>[31m-+<U+001B>[m
39-<U+001B>[31m- e := echo.New()<U+001B>[m
40-<U+001B>[31m- e.HideBanner = true<U+001B>[m
41-<U+001B>[31m- e.HidePort = true<U+001B>[m
42-<U+001B>[31m- e = httpserve.RegisterRoutes(e, a)<U+001B>[m
43-<U+001B>[31m- slog.Info("Starting server", "port", a.HttpPort)<U+001B>[m
44-<U+001B>[31m- slog.Error("Server error", e.Start(fmt.Sprintf(":%d", a.HttpPort)))<U+001B>[m
45-<U+001B>[31m-+<U+001B>[m
46-<U+001B>[31m- }<U+001B>[m
47-<U+001B>[31m-diff --git a/go.mod b/go.mod<U+001B>[m
48-<U+001B>[31m-index 35e2d3c..8a3ac59 100644<U+001B>[m
49-<U+001B>[31m---- a/go.mod<U+001B>[m
50-<U+001B>[31m-+++ b/go.mod<U+001B>[m
51-<U+001B>[31m-@@ -24,6 +24,7 @@ require (<U+001B>[m
52-<U+001B>[31m- github.com/gorilla/securecookie v1.1.1 // indirect<U+001B>[m
53-<U+001B>[31m- github.com/gorilla/sessions v1.2.1 // indirect<U+001B>[m
54-<U+001B>[31m- github.com/klauspost/compress v1.16.7 // indirect<U+001B>[m
55-<U+001B>[31m-+ github.com/kr/text v0.1.0 // indirect<U+001B>[m
56-<U+001B>[31m- github.com/labstack/gommon v0.4.0 // indirect<U+001B>[m
57-<U+001B>[31m- github.com/mattn/go-colorable v0.1.13 // indirect<U+001B>[m
58-<U+001B>[31m- github.com/mattn/go-isatty v0.0.19 // indirect<U+001B>[m
59-<U+001B>[31m-@@ -35,6 +36,7 @@ require (<U+001B>[m
60-<U+001B>[31m- github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect<U+001B>[m
61-<U+001B>[31m- github.com/opencontainers/runc v1.1.9 // indirect<U+001B>[m
62-<U+001B>[31m- github.com/pkg/errors v0.9.1 // indirect<U+001B>[m
63-<U+001B>[31m-+ github.com/rogpeppe/go-internal v1.11.0 // indirect<U+001B>[m
64-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3 // indirect<U+001B>[m
65-<U+001B>[31m- github.com/valyala/bytebufferpool v1.0.0 // indirect<U+001B>[m
66-<U+001B>[31m- github.com/valyala/fasttemplate v1.2.2 // indirect<U+001B>[m
67-<U+001B>[31m-@@ -45,5 +47,6 @@ require (<U+001B>[m
68-<U+001B>[31m- golang.org/x/text v0.11.0 // indirect<U+001B>[m
69-<U+001B>[31m- golang.org/x/time v0.3.0 // indirect<U+001B>[m
70-<U+001B>[31m- golang.org/x/tools v0.7.0 // indirect<U+001B>[m
71-<U+001B>[31m-+ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect<U+001B>[m
72-<U+001B>[31m- gotest.tools/v3 v3.5.0 // indirect<U+001B>[m
73-<U+001B>[31m- )<U+001B>[m
74-<U+001B>[31m-diff --git a/go.sum b/go.sum<U+001B>[m
75-<U+001B>[31m-index 7b9b857..17b0bcd 100644<U+001B>[m
76-<U+001B>[31m---- a/go.sum<U+001B>[m
77-<U+001B>[31m-+++ b/go.sum<U+001B>[m
78-<U+001B>[31m-@@ -39,6 +39,11 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI<U+001B>[m
79-<U+001B>[31m- github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=<U+001B>[m
80-<U+001B>[31m- github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=<U+001B>[m
81-<U+001B>[31m- github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=<U+001B>[m
82-<U+001B>[31m-+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=<U+001B>[m
83-<U+001B>[31m-+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=<U+001B>[m
84-<U+001B>[31m-+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=<U+001B>[m
85-<U+001B>[31m-+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=<U+001B>[m
86-<U+001B>[31m-+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=<U+001B>[m
87-<U+001B>[31m- github.com/labstack/echo-contrib v0.15.0 h1:9K+oRU265y4Mu9zpRDv3X+DGTqUALY6oRHCSZZKCRVU=<U+001B>[m
88-<U+001B>[31m- github.com/labstack/echo-contrib v0.15.0/go.mod h1:lei+qt5CLB4oa7VHTE0yEfQSEB9XTJI1LUqko9UWvo4=<U+001B>[m
89-<U+001B>[31m- github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4=<U+001B>[m
90-<U+001B>[31m-@@ -72,6 +77,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=<U+001B>[m
91-<U+001B>[31m- github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=<U+001B>[m
92-<U+001B>[31m- github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=<U+001B>[m
93-<U+001B>[31m- github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=<U+001B>[m
94-<U+001B>[31m-+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=<U+001B>[m
95-<U+001B>[31m-+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=<U+001B>[m
96-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=<U+001B>[m
97-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=<U+001B>[m
98-<U+001B>[31m- github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=<U+001B>[m
99-<U+001B>[31m-@@ -153,8 +160,9 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T<U+001B>[m
100-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
101-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
102-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
103-<U+001B>[31m--gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=<U+001B>[m
104-<U+001B>[31m- gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=<U+001B>[m
105-<U+001B>[31m-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=<U+001B>[m
106-<U+001B>[31m-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=<U+001B>[m
107-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=<U+001B>[m
108-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=<U+001B>[m
109-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=<U+001B>[m
110-<U+001B>[31m-diff --git a/internal/app/app.go b/internal/app/app.go<U+001B>[m
111-<U+001B>[31m-index c6f49ac..1dd44b8 100644<U+001B>[m
112-<U+001B>[31m---- a/internal/app/app.go<U+001B>[m
113-<U+001B>[31m-+++ b/internal/app/app.go<U+001B>[m
114-<U+001B>[31m-@@ -27,6 +27,7 @@ const (<U+001B>[m
115-<U+001B>[31m- type App struct {<U+001B>[m
116-<U+001B>[31m- TemplateFS fs.FS<U+001B>[m
117-<U+001B>[31m- PublicFS fs.FS<U+001B>[m
118-<U+001B>[31m-+ DB interface{}<U+001B>[m
119-<U+001B>[31m- BuildVersion string<U+001B>[m
120-<U+001B>[31m- BuildDir string<U+001B>[m
121-<U+001B>[31m- DBDir string<U+001B>[m
122-<U+001B>[31m-diff --git a/internal/app/sqlite.go b/internal/app/sqlite.go<U+001B>[m
123-<U+001B>[31m-index 9f1b1ab..ddc6a1e 100644<U+001B>[m
124-<U+001B>[31m---- a/internal/app/sqlite.go<U+001B>[m
125-<U+001B>[31m-+++ b/internal/app/sqlite.go<U+001B>[m
126-<U+001B>[31m-@@ -5,58 +5,78 @@ import (<U+001B>[m
127-<U+001B>[31m- "database/sql"<U+001B>[m
128-<U+001B>[31m- "fmt"<U+001B>[m
129-<U+001B>[31m- "os"<U+001B>[m
130-<U+001B>[31m-+ "path/filepath"<U+001B>[m
131-<U+001B>[31m- <U+001B>[m
132-<U+001B>[31m-- sqlite3 "github.com/mattn/go-sqlite3"<U+001B>[m
133-<U+001B>[31m-+ "github.com/bnema/gordon/internal/database/migrate"<U+001B>[m
134-<U+001B>[31m-+ "github.com/mattn/go-sqlite3"<U+001B>[m
135-<U+001B>[31m- )<U+001B>[m
136-<U+001B>[31m- <U+001B>[m
137-<U+001B>[31m--// Initialize in-memory SQLite database and returns its connection<U+001B>[m
138-<U+001B>[31m--func InitDB() (db *sql.DB, err error) {<U+001B>[m
139-<U+001B>[31m-- db, err = sql.Open("sqlite3", "file::memory?cache=shared")<U+001B>[m
140-<U+001B>[31m-- if err != nil {<U+001B>[m
141-<U+001B>[31m-- return nil, fmt.Errorf("failed to open in-memory database: %v", err)<U+001B>[m
142-<U+001B>[31m-- }<U+001B>[m
143-<U+001B>[31m-- return<U+001B>[m
144-<U+001B>[31m--}<U+001B>[m
145-<U+001B>[31m--<U+001B>[m
146-<U+001B>[31m--// CloseDB closes the database connection and backs up the in-memory database to disk<U+001B>[m
147-<U+001B>[31m--func CloseDB(db *sql.DB, a *App) error {<U+001B>[m
148-<U+001B>[31m-- if err := BackupDB(db, a); err != nil {<U+001B>[m
149-<U+001B>[31m-- return err<U+001B>[m
150-<U+001B>[31m-- }<U+001B>[m
151-<U+001B>[31m-+// InitializeDB initializes the SQLite database. If a database file exists on disk, it loads it into memory.<U+001B>[m
152-<U+001B>[31m-+// Otherwise, it creates a new in-memory database and bootstraps it.<U+001B>[m
153-<U+001B>[31m-+func InitializeDB(a *App) (*sql.DB, error) {<U+001B>[m
154-<U+001B>[31m-+ dbfp := a.GetDBFilePath()<U+001B>[m
155-<U+001B>[31m- <U+001B>[m
156-<U+001B>[31m-- if err := db.Close(); err != nil {<U+001B>[m
157-<U+001B>[31m-- return fmt.Errorf("failed to close database: %v", err)<U+001B>[m
158-<U+001B>[31m-+ // Check if the directory exists, if not create it<U+001B>[m
159-<U+001B>[31m-+ dir := filepath.Dir(a.DBDir)<U+001B>[m
160-<U+001B>[31m-+ fmt.Println("dir", dir)<U+001B>[m
161-<U+001B>[31m-+ if _, err := os.Stat(dir); os.IsNotExist(err) {<U+001B>[m
162-<U+001B>[31m-+ err = os.MkdirAll(dir, 0755)<U+001B>[m
163-<U+001B>[31m-+ if err != nil {<U+001B>[m
164-<U+001B>[31m-+ return nil, fmt.Errorf("failed to create directory: %v", err)<U+001B>[m
165-<U+001B>[31m-+ }<U+001B>[m
166-<U+001B>[31m- }<U+001B>[m
167-<U+001B>[31m- <U+001B>[m
168-<U+001B>[31m-- return nil<U+001B>[m
169-<U+001B>[31m--}<U+001B>[m
170-<U+001B>[31m-+ // If the database file doesn't exist on disk<U+001B>[m
171-<U+001B>[31m-+ if _, err := os.Stat(dbfp); os.IsNotExist(err) {<U+001B>[m
172-<U+001B>[31m-+ memDB, err := initInMemoryDB()<U+001B>[m
173-<U+001B>[31m-+ if err != nil {<U+001B>[m
174-<U+001B>[31m-+ return nil, err<U+001B>[m
175-<U+001B>[31m-+ }<U+001B>[m
176-<U+001B>[31m- <U+001B>[m
177-<U+001B>[31m--// LoadDBIntoMemory loads the database from disk into memory<U+001B>[m
178-<U+001B>[31m--func LoadDBIntoMemory(a *App) (*sql.DB, error) {<U+001B>[m
179-<U+001B>[31m-- dbfp := a.GetDBFilePath()<U+001B>[m
180-<U+001B>[31m-+ // Run the bootstrap<U+001B>[m
181-<U+001B>[31m-+ RunBootstrap(memDB)<U+001B>[m
182-<U+001B>[31m- <U+001B>[m
183-<U+001B>[31m-- if _, err := os.Stat(dbfp); err != nil {<U+001B>[m
184-<U+001B>[31m-- return nil, nil<U+001B>[m
185-<U+001B>[31m-+ // Explicitly backup the in-memory database to disk<U+001B>[m
186-<U+001B>[31m-+ err = BackupDB(memDB, a)<U+001B>[m
187-<U+001B>[31m-+ if err != nil {<U+001B>[m
188-<U+001B>[31m-+ return nil, fmt.Errorf("failed to backup in-memory database to disk: %v", err)<U+001B>[m
189-<U+001B>[31m-+ }<U+001B>[m
190-<U+001B>[31m- }<U+001B>[m
191-<U+001B>[31m- <U+001B>[m
192-<U+001B>[31m-- memDB, err := InitDB()<U+001B>[m
193-<U+001B>[31m-+ memDB, err := initInMemoryDB()<U+001B>[m
194-<U+001B>[31m- if err != nil {<U+001B>[m
195-<U+001B>[31m- return nil, err<U+001B>[m
196-<U+001B>[31m- }<U+001B>[m
197-<U+001B>[31m--<U+001B>[m
198-<U+001B>[31m- diskDB, err := sql.Open("sqlite3", dbfp)<U+001B>[m
199-<U+001B>[31m- if err != nil {<U+001B>[m
200-<U+001B>[31m- return nil, fmt.Errorf("failed to open database file: %v", err)<U+001B>[m
201-<U+001B>[31m- }<U+001B>[m
202-<U+001B>[31m-+ defer diskDB.Close()<U+001B>[m
203-<U+001B>[31m- <U+001B>[m
204-<U+001B>[31m- if err := transferData(diskDB, memDB); err != nil {<U+001B>[m
205-<U+001B>[31m- return nil, err<U+001B>[m
206-<U+001B>[31m- }<U+001B>[m
207-<U+001B>[31m--<U+001B>[m
208-<U+001B>[31m- return memDB, nil<U+001B>[m
209-<U+001B>[31m- }<U+001B>[m
210-<U+001B>[31m- <U+001B>[m
211-<U+001B>[31m--// transferData transfers data from srcDB to dstDB<U+001B>[m
212-<U+001B>[31m-+func initInMemoryDB() (*sql.DB, error) {<U+001B>[m
213-<U+001B>[31m-+ db, err := sql.Open("sqlite3", "file::memory?cache=shared")<U+001B>[m
214-<U+001B>[31m-+ if err != nil {<U+001B>[m
215-<U+001B>[31m-+ return nil, fmt.Errorf("failed to open in-memory database: %v", err)<U+001B>[m
216-<U+001B>[31m-+ }<U+001B>[m
217-<U+001B>[31m-+ return db, nil<U+001B>[m
218-<U+001B>[31m-+}<U+001B>[m
219-<U+001B>[31m-+<U+001B>[m
220-<U+001B>[31m-+func CloseAndBackupDB(db *sql.DB, a *App) error {<U+001B>[m
221-<U+001B>[31m-+ if err := BackupDB(db, a); err != nil {<U+001B>[m
222-<U+001B>[31m-+ return err<U+001B>[m
223-<U+001B>[31m-+ }<U+001B>[m
224-<U+001B>[31m-+ if err := db.Close(); err != nil {<U+001B>[m
225-<U+001B>[31m-+ return fmt.Errorf("failed to close database: %v", err)<U+001B>[m
226-<U+001B>[31m-+ }<U+001B>[m
227-<U+001B>[31m-+ return nil<U+001B>[m
228-<U+001B>[31m-+}<U+001B>[m
229-<U+001B>[31m-+<U+001B>[m
230-<U+001B>[31m- func transferData(srcDB, dstDB *sql.DB) error {<U+001B>[m
231-<U+001B>[31m- srcConn, err := srcDB.Conn(context.Background())<U+001B>[m
232-<U+001B>[31m- if err != nil {<U+001B>[m
233-<U+001B>[31m-@@ -74,35 +94,50 @@ func transferData(srcDB, dstDB *sql.DB) error {<U+001B>[m
234-<U+001B>[31m- return dstConn.Raw(func(dstRawConn interface{}) error {<U+001B>[m
235-<U+001B>[31m- srcSqlite3Conn := srcRawConn.(*sqlite3.SQLiteConn)<U+001B>[m
236-<U+001B>[31m- dstSqlite3Conn := dstRawConn.(*sqlite3.SQLiteConn)<U+001B>[m
237-<U+001B>[31m--<U+001B>[m
238-<U+001B>[31m- _, err := srcSqlite3Conn.Backup("main", dstSqlite3Conn, "main")<U+001B>[m
239-<U+001B>[31m- return err<U+001B>[m
240-<U+001B>[31m- })<U+001B>[m
241-<U+001B>[31m- })<U+001B>[m
242-<U+001B>[31m- }<U+001B>[m
243-<U+001B>[31m- <U+001B>[m
244-<U+001B>[31m--// BackupDB backs up the in-memory database to disk<U+001B>[m
245-<U+001B>[31m- func BackupDB(db *sql.DB, a *App) error {<U+001B>[m
246-<U+001B>[31m- dbfp := a.GetDBFilePath()<U+001B>[m
247-<U+001B>[31m--<U+001B>[m
248-<U+001B>[31m- conn, err := db.Conn(context.Background())<U+001B>[m
249-<U+001B>[31m- if err != nil {<U+001B>[m
250-<U+001B>[31m- return fmt.Errorf("failed to get underlying database connection: %v", err)<U+001B>[m
251-<U+001B>[31m- }<U+001B>[m
252-<U+001B>[31m-+ defer conn.Close()<U+001B>[m
253-<U+001B>[31m- <U+001B>[m
254-<U+001B>[31m- return conn.Raw(func(sqliteConn interface{}) error {<U+001B>[m
255-<U+001B>[31m- sqlite3Conn := sqliteConn.(*sqlite3.SQLiteConn)<U+001B>[m
256-<U+001B>[31m-- backupDB, err := sqlite3Conn.Backup(dbfp, sqlite3Conn, "main")<U+001B>[m
257-<U+001B>[31m-+ diskDB, err := sql.Open("sqlite3", dbfp)<U+001B>[m
258-<U+001B>[31m-+ fmt.Println("diskDB", diskDB)<U+001B>[m
259-<U+001B>[31m-+ if err != nil {<U+001B>[m
260-<U+001B>[31m-+ return fmt.Errorf("failed to open destination database file: %v", err)<U+001B>[m
261-<U+001B>[31m-+ }<U+001B>[m
262-<U+001B>[31m-+ defer diskDB.Close()<U+001B>[m
263-<U+001B>[31m-+<U+001B>[m
264-<U+001B>[31m-+ diskConn, err := diskDB.Conn(context.Background())<U+001B>[m
265-<U+001B>[31m- if err != nil {<U+001B>[m
266-<U+001B>[31m-- return fmt.Errorf("failed to create backup: %v", err)<U+001B>[m
267-<U+001B>[31m-+ return fmt.Errorf("failed to get connection from diskDB: %v", err)<U+001B>[m
268-<U+001B>[31m- }<U+001B>[m
269-<U+001B>[31m-+ defer diskConn.Close()<U+001B>[m
270-<U+001B>[31m-+<U+001B>[m
271-<U+001B>[31m-+ var backupDB *sqlite3.SQLiteBackup<U+001B>[m
272-<U+001B>[31m-+ err = diskConn.Raw(func(diskRawConn interface{}) error {<U+001B>[m
273-<U+001B>[31m-+ backupDB, err = sqlite3Conn.Backup("main", diskRawConn.(*sqlite3.SQLiteConn), "main")<U+001B>[m
274-<U+001B>[31m-+ return err<U+001B>[m
275-<U+001B>[31m-+ })<U+001B>[m
276-<U+001B>[31m- defer backupDB.Close()<U+001B>[m
277-<U+001B>[31m- <U+001B>[m
278-<U+001B>[31m- _, err = backupDB.Step(-1)<U+001B>[m
279-<U+001B>[31m- if err != nil {<U+001B>[m
280-<U+001B>[31m- return fmt.Errorf("failed to backup in-memory database: %v", err)<U+001B>[m
281-<U+001B>[31m- }<U+001B>[m
282-<U+001B>[31m--<U+001B>[m
283-<U+001B>[31m- return nil<U+001B>[m
284-<U+001B>[31m- })<U+001B>[m
285-<U+001B>[31m- }<U+001B>[m
286-<U+001B>[31m-+<U+001B>[m
287-<U+001B>[31m-+func RunBootstrap(db *sql.DB) error {<U+001B>[m
288-<U+001B>[31m-+ return migrate.CreateUserTable(db)<U+001B>[m
289-<U+001B>[31m-+}<U+001B>[m
290-<U+001B>[31m-diff --git a/internal/database/migrate/bootstrapdb.go b/internal/database/migrate/bootstrapdb.go<U+001B>[m
291-<U+001B>[31m-new file mode 100644<U+001B>[m
292-<U+001B>[31m-index 0000000..1f53246<U+001B>[m
293-<U+001B>[31m---- /dev/null<U+001B>[m
294-<U+001B>[31m-+++ b/internal/database/migrate/bootstrapdb.go<U+001B>[m
295-<U+001B>[31m-@@ -0,0 +1,24 @@<U+001B>[m
296-<U+001B>[31m-+package migrate<U+001B>[m
297-<U+001B>[31m-+<U+001B>[m
298-<U+001B>[31m-+import (<U+001B>[m
299-<U+001B>[31m-+ "database/sql"<U+001B>[m
300-<U+001B>[31m-+ "fmt"<U+001B>[m
301-<U+001B>[31m-+)<U+001B>[m
302-<U+001B>[31m-+<U+001B>[m
303-<U+001B>[31m-+// createUserTable creates the 'user' table in the provided SQLite database.<U+001B>[m
304-<U+001B>[31m-+func CreateUserTable(db *sql.DB) error {<U+001B>[m
305-<U+001B>[31m-+ createTableSQL := `<U+001B>[m
306-<U+001B>[31m-+ CREATE TABLE user (<U+001B>[m
307-<U+001B>[31m-+ id INTEGER PRIMARY KEY AUTOINCREMENT,<U+001B>[m
308-<U+001B>[31m-+ username TEXT NOT NULL,<U+001B>[m
309-<U+001B>[31m-+ password TEXT NOT NULL, -- This should be hashed and salted in a real-world scenario.<U+001B>[m
310-<U+001B>[31m-+ oauth_token TEXT<U+001B>[m
311-<U+001B>[31m-+ );`<U+001B>[m
312-<U+001B>[31m-+<U+001B>[m
313-<U+001B>[31m-+ _, err := db.Exec(createTableSQL)<U+001B>[m
314-<U+001B>[31m-+ if err != nil {<U+001B>[m
315-<U+001B>[31m-+ return fmt.Errorf("failed to create user table: %v", err)<U+001B>[m
316-<U+001B>[31m-+ }<U+001B>[m
317-<U+001B>[31m-+<U+001B>[m
318-<U+001B>[31m-+ return nil<U+001B>[m
319-<U+001B>[31m-+}<U+001B>[m
320-<U+001B>[31m-diff --git a/internal/httpserve/handler/adminroutes.go b/internal/httpserve/handler/adminroutes.go<U+001B>[m
321-<U+001B>[31m-index 8701ae3..f4acd64 100644<U+001B>[m
322-<U+001B>[31m---- a/internal/httpserve/handler/adminroutes.go<U+001B>[m
323-<U+001B>[31m-+++ b/internal/httpserve/handler/adminroutes.go<U+001B>[m
324-<U+001B>[31m-@@ -1,8 +1,6 @@<U+001B>[m
325-<U+001B>[31m- package handler<U+001B>[m
326-<U+001B>[31m- <U+001B>[m
327-<U+001B>[31m- import (<U+001B>[m
328-<U+001B>[31m-- "fmt"<U+001B>[m
329-<U+001B>[31m--<U+001B>[m
330-<U+001B>[31m- "github.com/bnema/gordon/internal/app"<U+001B>[m
331-<U+001B>[31m- "github.com/bnema/gordon/internal/gotemplate/render"<U+001B>[m
332-<U+001B>[31m- "github.com/bnema/gordon/internal/httpserve/middleware"<U+001B>[m
333-<U+001B>[1mdiff --git a/internal/httpserve/handler/oauth.go b/internal/httpserve/handler/oauth.go<U+001B>[m
334-<U+001B>[1mindex bd40379..b876c75 100644<U+001B>[m
335-<U+001B>[1m--- a/internal/httpserve/handler/oauth.go<U+001B>[m
336-<U+001B>[1m+++ b/internal/httpserve/handler/oauth.go<U+001B>[m
337-<U+001B>[36m@@ -12,6 +12,7 @@<U+001B>[m <U+001B>[mimport (<U+001B>[m
338- "github.com/markbates/goth/gothic"<U+001B>[m
339- "github.com/markbates/goth/providers/github"<U+001B>[m
340- "net/http"<U+001B>[m
341-<U+001B>[32m+<U+001B>[m <U+001B>[32m"os"<U+001B>[m
342- )<U+001B>[m
343- <U+001B>[m
344- var providerNames []string<U+001B>[m
345-<U+001B>[1mdiff --git a/internal/httpserve/router.go b/internal/httpserve/router.go<U+001B>[m
346-<U+001B>[1mindex bc1368c..edd2748 100644<U+001B>[m
347-<U+001B>[1m--- a/internal/httpserve/router.go<U+001B>[m
348-<U+001B>[1m+++ b/internal/httpserve/router.go<U+001B>[m
349-<U+001B>[36m@@ -19,34 +19,19 @@<U+001B>[m <U+001B>[mfunc RegisterRoutes(e *echo.Echo, a *app.App) *echo.Echo {<U+001B>[m
350- // Use session middleware<U+001B>[m
351- // Add session middleware<U+001B>[m
352- e.Use(session.Middleware(sessions.NewCookieStore([]byte(os.Getenv("SECRET")))))<U+001B>[m
353-<U+001B>[31m- // e.Use(middleware.SecureRoutes())<U+001B>[m
354- e.Use(middleware.ColorSchemeDetection)<U+001B>[m
355- e.Use(middleware.LanguageDetection)<U+001B>[m
356- <U+001B>[m
357- // Register routes<U+001B>[m
358-<U+001B>[31m-<U+001B>[m
359-<U+001B>[31m- // Serve admin routes<U+001B>[m
360- bindAdminRoute(e, a, AdminPath)<U+001B>[m
361-<U+001B>[31m- // Serve static files<U+001B>[m
362- bindStaticRoute(e, a, "/*")<U+001B>[m
363-<U+001B>[32m+<U+001B>[m <U+001B>[32mbindLoginRoute(e, a, AdminPath)<U+001B>[m
364-<U+001B>[32m+<U+001B>[m
365- // Protect the root path with a 403<U+001B>[m
366- e.GET("/", func(c echo.Context) error {<U+001B>[m
367- return c.String(403, "403 Forbidden")<U+001B>[m
368- })<U+001B>[m
369- <U+001B>[m
370-<U+001B>[31m- e.GET(a.AdminPath+"/login", func(c echo.Context) error {<U+001B>[m
371-<U+001B>[31m- return handler.RenderLoginPage(c, a)<U+001B>[m
372-<U+001B>[31m- })<U+001B>[m
373-<U+001B>[31m- e.GET(a.AdminPath+"/login/:provider", func(c echo.Context) error {<U+001B>[m
374-<U+001B>[31m- return handler.StartOAuth(c, a)<U+001B>[m
375-<U+001B>[31m- })<U+001B>[m
376-<U+001B>[31m- e.GET(a.OauthCallbackURL, func(c echo.Context) error {<U+001B>[m
377-<U+001B>[31m- return handler.OAuthCallback(c, a)<U+001B>[m
378-<U+001B>[31m- })<U+001B>[m
379-<U+001B>[31m- e.GET(a.AdminPath+"/logout", func(c echo.Context) error {<U+001B>[m
380-<U+001B>[31m- return handler.Logout(c, a)<U+001B>[m
381-<U+001B>[31m- })<U+001B>[m
382-<U+001B>[31m-<U+001B>[m
383- return e<U+001B>[m
384- }<U+001B>[m
385- <U+001B>[m
386-<U+001B>[36m@@ -61,3 +46,18 @@<U+001B>[m <U+001B>[mfunc bindAdminRoute(e *echo.Echo, a *app.App, path string) {<U+001B>[m
387- return handler.AdminRoute(c, a)<U+001B>[m
388- })<U+001B>[m
389- }<U+001B>[m
390-<U+001B>[32m+<U+001B>[m
391-<U+001B>[32m+<U+001B>[m<U+001B>[32mfunc bindLoginRoute(e *echo.Echo, a *app.App, adminPath string) {<U+001B>[m
392-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/login", func(c echo.Context) error {<U+001B>[m
393-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.RenderLoginPage(c, a)<U+001B>[m
394-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
395-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/login/:provider", func(c echo.Context) error {<U+001B>[m
396-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.StartOAuth(c, a)<U+001B>[m
397-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
398-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(a.OauthCallbackURL, func(c echo.Context) error {<U+001B>[m
399-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.OAuthCallback(c, a)<U+001B>[m
400-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
401-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/logout", func(c echo.Context) error {<U+001B>[m
402-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.Logout(c, a)<U+001B>[m
403-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
404-<U+001B>[32m+<U+001B>[m<U+001B>[32m}<U+001B>[m
D s="flex flex-row items-center"> +0 -1192
@@ -1,1192 +0,0 @@
1-
2- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
3-
4- Commands marked with * may be preceded by a number, _<U+0008>N.
5- Notes in parentheses indicate the behavior if _<U+0008>N is given.
6- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
7-
8- h H Display this help.
9- q :q Q :Q ZZ Exit.
10- ---------------------------------------------------------------------------
11-
12- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
13-
14- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
15- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
16- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
17- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
18- z * Forward one window (and set window to _<U+0008>N).
19- w * Backward one window (and set window to _<U+0008>N).
20- ESC-SPACE * Forward one window, but don't stop at end-of-file.
21- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
22- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
23- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
24- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
25- ESC-} ^RightArrow Right to last column displayed.
26- ESC-{ ^LeftArrow Left to first column.
27- F Forward forever; like "tail -f".
28- ESC-F Like F but stop when search pattern is found.
29- r ^R ^L Repaint screen.
30- R Repaint screen, discarding buffered input.
31- ---------------------------------------------------
32- Default "window" is the screen height.
33- Default "half-window" is half of the screen height.
34- ---------------------------------------------------------------------------
35-
36- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
37-
38- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
39- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
40- n * Repeat previous search (for _<U+0008>N-th occurrence).
41- N * Repeat previous search in reverse direction.
42- ESC-n * Repeat previous search, spanning files.
43- ESC-N * Repeat previous search, reverse dir. & spanning files.
44- ESC-u Undo (toggle) search highlighting.
45- ESC-U Clear search highlighting.
46- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
47- ---------------------------------------------------
48- A search pattern may begin with one or more of:
49- ^N or ! Search for NON-matching lines.
50- ^E or * Search multiple files (pass thru END OF FILE).
51- ^F or @ Start search at FIRST file (for /) or last file (for ?).
52- ^K Highlight matches, but don't move (KEEP position).
53- ^R Don't use REGULAR EXPRESSIONS.
54- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
55- ^W WRAP search if no match found.
56- ---------------------------------------------------------------------------
57-
58- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
59-
60- g < ESC-< * Go to first line in file (or line _<U+0008>N).
61- G > ESC-> * Go to last line in file (or line _<U+0008>N).
62- p % * Go to beginning of file (or _<U+0008>N percent into file).
63- t * Go to the (_<U+0008>N-th) next tag.
64- T * Go to the (_<U+0008>N-th) previous tag.
65- { ( [ * Find close bracket } ) ].
66- } ) ] * Find open bracket { ( [.
67- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
68- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
69- ---------------------------------------------------
70- Each "find close bracket" command goes forward to the close bracket
71- matching the (_<U+0008>N-th) open bracket in the top line.
72- Each "find open bracket" command goes backward to the open bracket
73- matching the (_<U+0008>N-th) close bracket in the bottom line.
74-
75- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
76- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
77- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
78- '' Go to the previous position.
79- ^X^X Same as '.
80- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
81- ---------------------------------------------------
82- A mark is any upper-case or lower-case letter.
83- Certain marks are predefined:
84- ^ means beginning of the file
85- $ means end of the file
86- ---------------------------------------------------------------------------
87-
88- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
89-
90- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
91- ^X^V Same as :e.
92- :n * Examine the (_<U+0008>N-th) next file from the command line.
93- :p * Examine the (_<U+0008>N-th) previous file from the command line.
94- :x * Examine the first (or _<U+0008>N-th) file from the command line.
95- :d Delete the current file from the command line list.
96- = ^G :f Print current file name.
97- ---------------------------------------------------------------------------
98-
99- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
100-
101- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
102- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
103- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
104- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
105- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
106-
107- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
108- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
109- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
110- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
111- v Edit the current file with $VISUAL or $EDITOR.
112- V Print version number of "less".
113- ---------------------------------------------------------------------------
114-
115- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
116-
117- Most options may be changed either on the command line,
118- or from within less by using the - or -- command.
119- Options may be given in one of two forms: either a single
120- character preceded by a -, or a name preceded by --.
121-
122- -? ........ --help
123- Display help (from command line).
124- -a ........ --search-skip-screen
125- Search skips current screen.
126- -A ........ --SEARCH-SKIP-SCREEN
127- Search starts just after target line.
128- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
129- Number of buffers.
130- -B ........ --auto-buffers
131- Don't automatically allocate buffers for pipes.
132- -c ........ --clear-screen
133- Repaint by clearing rather than scrolling.
134- -d ........ --dumb
135- Dumb terminal.
136- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
137- Set screen colors.
138- -e -E .... --quit-at-eof --QUIT-AT-EOF
139- Quit at end of file.
140- -f ........ --force
141- Force open non-regular files.
142- -F ........ --quit-if-one-screen
143- Quit if entire file fits on first screen.
144- -g ........ --hilite-search
145- Highlight only last match for searches.
146- -G ........ --HILITE-SEARCH
147- Don't highlight any matches for searches.
148- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
149- Backward scroll limit.
150- -i ........ --ignore-case
151- Ignore case in searches that do not contain uppercase.
152- -I ........ --IGNORE-CASE
153- Ignore case in all searches.
154- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
155- Screen position of target lines.
156- -J ........ --status-column
157- Display a status column at left edge of screen.
158- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
159- Use a lesskey file.
160- -K ........ --quit-on-intr
161- Exit less in response to ctrl-C.
162- -L ........ --no-lessopen
163- Ignore the LESSOPEN environment variable.
164- -m -M .... --long-prompt --LONG-PROMPT
165- Set prompt style.
166- -n ......... --line-numbers
167- Suppress line numbers in prompts and messages.
168- -N ......... --LINE-NUMBERS
169- Display line number at start of each line.
170- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
171- Copy to log file (standard input only).
172- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
173- Copy to log file (unconditionally overwrite).
174- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
175- Start at pattern (from command line).
176- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
177- Define new prompt.
178- -q -Q .... --quiet --QUIET --silent --SILENT
179- Quiet the terminal bell.
180- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
181- Output "raw" control characters.
182- -s ........ --squeeze-blank-lines
183- Squeeze multiple blank lines.
184- -S ........ --chop-long-lines
185- Chop (truncate) long lines rather than wrapping.
186- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
187- Find a tag.
188- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
189- Use an alternate tags file.
190- -u -U .... --underline-special --UNDERLINE-SPECIAL
191- Change handling of backspaces, tabs and carriage returns.
192- -V ........ --version
193- Display the version number of "less".
194- -w ........ --hilite-unread
195- Highlight first new line after forward-screen.
196- -W ........ --HILITE-UNREAD
197- Highlight first new line after any forward movement.
198- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
199- Set tab stops.
200- -X ........ --no-init
201- Don't use termcap init/deinit strings.
202- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
203- Forward scroll limit.
204- -z [_<U+0008>N] .... --window=[_<U+0008>N]
205- Set size of window.
206- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
207- Set shell quote characters.
208- -~ ........ --tilde
209- Don't display tildes after end of file.
210- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
211- Set horizontal scroll amount (0 = one half screen width).
212- --exit-follow-on-close
213- Exit F command on a pipe when writer closes pipe.
214- --file-size
215- Automatically determine the size of the input file.
216- --follow-name
217- The F command changes files if the input file is renamed.
218- --header=[_<U+0008>N[,_<U+0008>M]]
219- Use N lines and M columns to display file headers.
220- --incsearch
221- Search file as each pattern character is typed in.
222- --intr=_<U+0008>C
223- Use _<U+0008>C instead of ^X to interrupt a read.
224- --line-num-width=_<U+0008>N
225- Set the width of the -N line number field to _<U+0008>N characters.
226- --modelines=_<U+0008>N
227- Read _<U+0008>N lines from the input file and look for vim modelines.
228- --mouse
229- Enable mouse input.
230- --no-keypad
231- Don't send termcap keypad init/deinit strings.
232- --no-histdups
233- Remove duplicates from command history.
234- --no-number-headers
235- Don't give line numbers to header lines.
236- --no-search-headers
237- Don't search in header lines or columns.
238- --no-vbell
239- Disable the terminal's visual bell.
240- --redraw-on-quit
241- Redraw final screen when quitting.
242- --rscroll=_<U+0008>C
243- Set the character used to mark truncated lines.
244- --save-marks
245- Retain marks across invocations of less.
246- --search-options=[EFKNRW-]
247- Set default options for every search.
248- --show-preproc-errors
249- Display a message if preprocessor exits with an error status.
250- --proc-backspace
251- Process backspaces for bold/underline.
252- --SPECIAL-BACKSPACE
253- Treat backspaces as control characters.
254- --proc-return
255- Delete carriage returns before newline.
256- --SPECIAL-RETURN
257- Treat carriage returns as control characters.
258- --proc-tab
259- Expand tabs to spaces.
260- --SPECIAL-TAB
261- Treat tabs as control characters.
262- --status-col-width=_<U+0008>N
263- Set the width of the -J status column to _<U+0008>N characters.
264- --status-line
265- Highlight or color the entire line containing a mark.
266- --use-backslash
267- Subsequent options use backslash as escape char.
268- --use-color
269- Enables colored text.
270- --wheel-lines=_<U+0008>N
271- Each click of the mouse wheel moves _<U+0008>N lines.
272- --wordwrap
273- Wrap lines at spaces.
274-
275-
276- ---------------------------------------------------------------------------
277-
278- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
279-
280- These keys can be used to edit text being entered
281- on the "command line" at the bottom of the screen.
282-
283- RightArrow ..................... ESC-l ... Move cursor right one character.
284- LeftArrow ...................... ESC-h ... Move cursor left one character.
285- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
286- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
287- HOME ........................... ESC-0 ... Move cursor to start of line.
288- END ............................ ESC-$ ... Move cursor to end of line.
289- BACKSPACE ................................ Delete char to left of cursor.
290- DELETE ......................... ESC-x ... Delete char under cursor.
291- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
292- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
293- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
294- UpArrow ........................ ESC-k ... Retrieve previous command line.
295- DownArrow ...................... ESC-j ... Retrieve next command line.
296- TAB ...................................... Complete filename & cycle.
297- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
298- ctrl-L ................................... Complete filename, list all.
299-
300- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
301-
302- Commands marked with * may be preceded by a number, _<U+0008>N.
303- Notes in parentheses indicate the behavior if _<U+0008>N is given.
304- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
305-
306- h H Display this help.
307- q :q Q :Q ZZ Exit.
308- ---------------------------------------------------------------------------
309-
310- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
311-
312- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
313- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
314- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
315- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
316- z * Forward one window (and set window to _<U+0008>N).
317- w * Backward one window (and set window to _<U+0008>N).
318- ESC-SPACE * Forward one window, but don't stop at end-of-file.
319- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
320- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
321- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
322- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
323- ESC-} ^RightArrow Right to last column displayed.
324- ESC-{ ^LeftArrow Left to first column.
325- F Forward forever; like "tail -f".
326- ESC-F Like F but stop when search pattern is found.
327- r ^R ^L Repaint screen.
328- R Repaint screen, discarding buffered input.
329- ---------------------------------------------------
330- Default "window" is the screen height.
331- Default "half-window" is half of the screen height.
332- ---------------------------------------------------------------------------
333-
334- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
335-
336- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
337- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
338- n * Repeat previous search (for _<U+0008>N-th occurrence).
339- N * Repeat previous search in reverse direction.
340- ESC-n * Repeat previous search, spanning files.
341- ESC-N * Repeat previous search, reverse dir. & spanning files.
342- ESC-u Undo (toggle) search highlighting.
343- ESC-U Clear search highlighting.
344- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
345- ---------------------------------------------------
346- A search pattern may begin with one or more of:
347- ^N or ! Search for NON-matching lines.
348- ^E or * Search multiple files (pass thru END OF FILE).
349- ^F or @ Start search at FIRST file (for /) or last file (for ?).
350- ^K Highlight matches, but don't move (KEEP position).
351- ^R Don't use REGULAR EXPRESSIONS.
352- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
353- ^W WRAP search if no match found.
354- ---------------------------------------------------------------------------
355-
356- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
357-
358- g < ESC-< * Go to first line in file (or line _<U+0008>N).
359- G > ESC-> * Go to last line in file (or line _<U+0008>N).
360- p % * Go to beginning of file (or _<U+0008>N percent into file).
361- t * Go to the (_<U+0008>N-th) next tag.
362- T * Go to the (_<U+0008>N-th) previous tag.
363- { ( [ * Find close bracket } ) ].
364- } ) ] * Find open bracket { ( [.
365- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
366- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
367- ---------------------------------------------------
368- Each "find close bracket" command goes forward to the close bracket
369- matching the (_<U+0008>N-th) open bracket in the top line.
370- Each "find open bracket" command goes backward to the open bracket
371- matching the (_<U+0008>N-th) close bracket in the bottom line.
372-
373- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
374- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
375- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
376- '' Go to the previous position.
377- ^X^X Same as '.
378- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
379- ---------------------------------------------------
380- A mark is any upper-case or lower-case letter.
381- Certain marks are predefined:
382- ^ means beginning of the file
383- $ means end of the file
384- ---------------------------------------------------------------------------
385-
386- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
387-
388- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
389- ^X^V Same as :e.
390- :n * Examine the (_<U+0008>N-th) next file from the command line.
391- :p * Examine the (_<U+0008>N-th) previous file from the command line.
392- :x * Examine the first (or _<U+0008>N-th) file from the command line.
393- :d Delete the current file from the command line list.
394- = ^G :f Print current file name.
395- ---------------------------------------------------------------------------
396-
397- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
398-
399- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
400- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
401- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
402- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
403- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
404-
405- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
406- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
407- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
408- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
409- v Edit the current file with $VISUAL or $EDITOR.
410- V Print version number of "less".
411- ---------------------------------------------------------------------------
412-
413- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
414-
415- Most options may be changed either on the command line,
416- or from within less by using the - or -- command.
417- Options may be given in one of two forms: either a single
418- character preceded by a -, or a name preceded by --.
419-
420- -? ........ --help
421- Display help (from command line).
422- -a ........ --search-skip-screen
423- Search skips current screen.
424- -A ........ --SEARCH-SKIP-SCREEN
425- Search starts just after target line.
426- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
427- Number of buffers.
428- -B ........ --auto-buffers
429- Don't automatically allocate buffers for pipes.
430- -c ........ --clear-screen
431- Repaint by clearing rather than scrolling.
432- -d ........ --dumb
433- Dumb terminal.
434- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
435- Set screen colors.
436- -e -E .... --quit-at-eof --QUIT-AT-EOF
437- Quit at end of file.
438- -f ........ --force
439- Force open non-regular files.
440- -F ........ --quit-if-one-screen
441- Quit if entire file fits on first screen.
442- -g ........ --hilite-search
443- Highlight only last match for searches.
444- -G ........ --HILITE-SEARCH
445- Don't highlight any matches for searches.
446- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
447- Backward scroll limit.
448- -i ........ --ignore-case
449- Ignore case in searches that do not contain uppercase.
450- -I ........ --IGNORE-CASE
451- Ignore case in all searches.
452- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
453- Screen position of target lines.
454- -J ........ --status-column
455- Display a status column at left edge of screen.
456- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
457- Use a lesskey file.
458- -K ........ --quit-on-intr
459- Exit less in response to ctrl-C.
460- -L ........ --no-lessopen
461- Ignore the LESSOPEN environment variable.
462- -m -M .... --long-prompt --LONG-PROMPT
463- Set prompt style.
464- -n ......... --line-numbers
465- Suppress line numbers in prompts and messages.
466- -N ......... --LINE-NUMBERS
467- Display line number at start of each line.
468- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
469- Copy to log file (standard input only).
470- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
471- Copy to log file (unconditionally overwrite).
472- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
473- Start at pattern (from command line).
474- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
475- Define new prompt.
476- -q -Q .... --quiet --QUIET --silent --SILENT
477- Quiet the terminal bell.
478- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
479- Output "raw" control characters.
480- -s ........ --squeeze-blank-lines
481- Squeeze multiple blank lines.
482- -S ........ --chop-long-lines
483- Chop (truncate) long lines rather than wrapping.
484- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
485- Find a tag.
486- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
487- Use an alternate tags file.
488- -u -U .... --underline-special --UNDERLINE-SPECIAL
489- Change handling of backspaces, tabs and carriage returns.
490- -V ........ --version
491- Display the version number of "less".
492- -w ........ --hilite-unread
493- Highlight first new line after forward-screen.
494- -W ........ --HILITE-UNREAD
495- Highlight first new line after any forward movement.
496- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
497- Set tab stops.
498- -X ........ --no-init
499- Don't use termcap init/deinit strings.
500- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
501- Forward scroll limit.
502- -z [_<U+0008>N] .... --window=[_<U+0008>N]
503- Set size of window.
504- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
505- Set shell quote characters.
506- -~ ........ --tilde
507- Don't display tildes after end of file.
508- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
509- Set horizontal scroll amount (0 = one half screen width).
510- --exit-follow-on-close
511- Exit F command on a pipe when writer closes pipe.
512- --file-size
513- Automatically determine the size of the input file.
514- --follow-name
515- The F command changes files if the input file is renamed.
516- --header=[_<U+0008>N[,_<U+0008>M]]
517- Use N lines and M columns to display file headers.
518- --incsearch
519- Search file as each pattern character is typed in.
520- --intr=_<U+0008>C
521- Use _<U+0008>C instead of ^X to interrupt a read.
522- --line-num-width=_<U+0008>N
523- Set the width of the -N line number field to _<U+0008>N characters.
524- --modelines=_<U+0008>N
525- Read _<U+0008>N lines from the input file and look for vim modelines.
526- --mouse
527- Enable mouse input.
528- --no-keypad
529- Don't send termcap keypad init/deinit strings.
530- --no-histdups
531- Remove duplicates from command history.
532- --no-number-headers
533- Don't give line numbers to header lines.
534- --no-search-headers
535- Don't search in header lines or columns.
536- --no-vbell
537- Disable the terminal's visual bell.
538- --redraw-on-quit
539- Redraw final screen when quitting.
540- --rscroll=_<U+0008>C
541- Set the character used to mark truncated lines.
542- --save-marks
543- Retain marks across invocations of less.
544- --search-options=[EFKNRW-]
545- Set default options for every search.
546- --show-preproc-errors
547- Display a message if preprocessor exits with an error status.
548- --proc-backspace
549- Process backspaces for bold/underline.
550- --SPECIAL-BACKSPACE
551- Treat backspaces as control characters.
552- --proc-return
553- Delete carriage returns before newline.
554- --SPECIAL-RETURN
555- Treat carriage returns as control characters.
556- --proc-tab
557- Expand tabs to spaces.
558- --SPECIAL-TAB
559- Treat tabs as control characters.
560- --status-col-width=_<U+0008>N
561- Set the width of the -J status column to _<U+0008>N characters.
562- --status-line
563- Highlight or color the entire line containing a mark.
564- --use-backslash
565- Subsequent options use backslash as escape char.
566- --use-color
567- Enables colored text.
568- --wheel-lines=_<U+0008>N
569- Each click of the mouse wheel moves _<U+0008>N lines.
570- --wordwrap
571- Wrap lines at spaces.
572-
573-
574- ---------------------------------------------------------------------------
575-
576- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
577-
578- These keys can be used to edit text being entered
579- on the "command line" at the bottom of the screen.
580-
581- RightArrow ..................... ESC-l ... Move cursor right one character.
582- LeftArrow ...................... ESC-h ... Move cursor left one character.
583- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
584- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
585- HOME ........................... ESC-0 ... Move cursor to start of line.
586- END ............................ ESC-$ ... Move cursor to end of line.
587- BACKSPACE ................................ Delete char to left of cursor.
588- DELETE ......................... ESC-x ... Delete char under cursor.
589- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
590- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
591- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
592- UpArrow ........................ ESC-k ... Retrieve previous command line.
593- DownArrow ...................... ESC-j ... Retrieve next command line.
594- TAB ...................................... Complete filename & cycle.
595- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
596- ctrl-L ................................... Complete filename, list all.
597-
598- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
599-
600- Commands marked with * may be preceded by a number, _<U+0008>N.
601- Notes in parentheses indicate the behavior if _<U+0008>N is given.
602- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
603-
604- h H Display this help.
605- q :q Q :Q ZZ Exit.
606- ---------------------------------------------------------------------------
607-
608- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
609-
610- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
611- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
612- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
613- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
614- z * Forward one window (and set window to _<U+0008>N).
615- w * Backward one window (and set window to _<U+0008>N).
616- ESC-SPACE * Forward one window, but don't stop at end-of-file.
617- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
618- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
619- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
620- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
621- ESC-} ^RightArrow Right to last column displayed.
622- ESC-{ ^LeftArrow Left to first column.
623- F Forward forever; like "tail -f".
624- ESC-F Like F but stop when search pattern is found.
625- r ^R ^L Repaint screen.
626- R Repaint screen, discarding buffered input.
627- ---------------------------------------------------
628- Default "window" is the screen height.
629- Default "half-window" is half of the screen height.
630- ---------------------------------------------------------------------------
631-
632- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
633-
634- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
635- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
636- n * Repeat previous search (for _<U+0008>N-th occurrence).
637- N * Repeat previous search in reverse direction.
638- ESC-n * Repeat previous search, spanning files.
639- ESC-N * Repeat previous search, reverse dir. & spanning files.
640- ESC-u Undo (toggle) search highlighting.
641- ESC-U Clear search highlighting.
642- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
643- ---------------------------------------------------
644- A search pattern may begin with one or more of:
645- ^N or ! Search for NON-matching lines.
646- ^E or * Search multiple files (pass thru END OF FILE).
647- ^F or @ Start search at FIRST file (for /) or last file (for ?).
648- ^K Highlight matches, but don't move (KEEP position).
649- ^R Don't use REGULAR EXPRESSIONS.
650- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
651- ^W WRAP search if no match found.
652- ---------------------------------------------------------------------------
653-
654- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
655-
656- g < ESC-< * Go to first line in file (or line _<U+0008>N).
657- G > ESC-> * Go to last line in file (or line _<U+0008>N).
658- p % * Go to beginning of file (or _<U+0008>N percent into file).
659- t * Go to the (_<U+0008>N-th) next tag.
660- T * Go to the (_<U+0008>N-th) previous tag.
661- { ( [ * Find close bracket } ) ].
662- } ) ] * Find open bracket { ( [.
663- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
664- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
665- ---------------------------------------------------
666- Each "find close bracket" command goes forward to the close bracket
667- matching the (_<U+0008>N-th) open bracket in the top line.
668- Each "find open bracket" command goes backward to the open bracket
669- matching the (_<U+0008>N-th) close bracket in the bottom line.
670-
671- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
672- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
673- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
674- '' Go to the previous position.
675- ^X^X Same as '.
676- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
677- ---------------------------------------------------
678- A mark is any upper-case or lower-case letter.
679- Certain marks are predefined:
680- ^ means beginning of the file
681- $ means end of the file
682- ---------------------------------------------------------------------------
683-
684- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
685-
686- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
687- ^X^V Same as :e.
688- :n * Examine the (_<U+0008>N-th) next file from the command line.
689- :p * Examine the (_<U+0008>N-th) previous file from the command line.
690- :x * Examine the first (or _<U+0008>N-th) file from the command line.
691- :d Delete the current file from the command line list.
692- = ^G :f Print current file name.
693- ---------------------------------------------------------------------------
694-
695- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
696-
697- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
698- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
699- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
700- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
701- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
702-
703- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
704- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
705- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
706- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
707- v Edit the current file with $VISUAL or $EDITOR.
708- V Print version number of "less".
709- ---------------------------------------------------------------------------
710-
711- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
712-
713- Most options may be changed either on the command line,
714- or from within less by using the - or -- command.
715- Options may be given in one of two forms: either a single
716- character preceded by a -, or a name preceded by --.
717-
718- -? ........ --help
719- Display help (from command line).
720- -a ........ --search-skip-screen
721- Search skips current screen.
722- -A ........ --SEARCH-SKIP-SCREEN
723- Search starts just after target line.
724- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
725- Number of buffers.
726- -B ........ --auto-buffers
727- Don't automatically allocate buffers for pipes.
728- -c ........ --clear-screen
729- Repaint by clearing rather than scrolling.
730- -d ........ --dumb
731- Dumb terminal.
732- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
733- Set screen colors.
734- -e -E .... --quit-at-eof --QUIT-AT-EOF
735- Quit at end of file.
736- -f ........ --force
737- Force open non-regular files.
738- -F ........ --quit-if-one-screen
739- Quit if entire file fits on first screen.
740- -g ........ --hilite-search
741- Highlight only last match for searches.
742- -G ........ --HILITE-SEARCH
743- Don't highlight any matches for searches.
744- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
745- Backward scroll limit.
746- -i ........ --ignore-case
747- Ignore case in searches that do not contain uppercase.
748- -I ........ --IGNORE-CASE
749- Ignore case in all searches.
750- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
751- Screen position of target lines.
752- -J ........ --status-column
753- Display a status column at left edge of screen.
754- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
755- Use a lesskey file.
756- -K ........ --quit-on-intr
757- Exit less in response to ctrl-C.
758- -L ........ --no-lessopen
759- Ignore the LESSOPEN environment variable.
760- -m -M .... --long-prompt --LONG-PROMPT
761- Set prompt style.
762- -n ......... --line-numbers
763- Suppress line numbers in prompts and messages.
764- -N ......... --LINE-NUMBERS
765- Display line number at start of each line.
766- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
767- Copy to log file (standard input only).
768- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
769- Copy to log file (unconditionally overwrite).
770- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
771- Start at pattern (from command line).
772- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
773- Define new prompt.
774- -q -Q .... --quiet --QUIET --silent --SILENT
775- Quiet the terminal bell.
776- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
777- Output "raw" control characters.
778- -s ........ --squeeze-blank-lines
779- Squeeze multiple blank lines.
780- -S ........ --chop-long-lines
781- Chop (truncate) long lines rather than wrapping.
782- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
783- Find a tag.
784- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
785- Use an alternate tags file.
786- -u -U .... --underline-special --UNDERLINE-SPECIAL
787- Change handling of backspaces, tabs and carriage returns.
788- -V ........ --version
789- Display the version number of "less".
790- -w ........ --hilite-unread
791- Highlight first new line after forward-screen.
792- -W ........ --HILITE-UNREAD
793- Highlight first new line after any forward movement.
794- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
795- Set tab stops.
796- -X ........ --no-init
797- Don't use termcap init/deinit strings.
798- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
799- Forward scroll limit.
800- -z [_<U+0008>N] .... --window=[_<U+0008>N]
801- Set size of window.
802- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
803- Set shell quote characters.
804- -~ ........ --tilde
805- Don't display tildes after end of file.
806- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
807- Set horizontal scroll amount (0 = one half screen width).
808- --exit-follow-on-close
809- Exit F command on a pipe when writer closes pipe.
810- --file-size
811- Automatically determine the size of the input file.
812- --follow-name
813- The F command changes files if the input file is renamed.
814- --header=[_<U+0008>N[,_<U+0008>M]]
815- Use N lines and M columns to display file headers.
816- --incsearch
817- Search file as each pattern character is typed in.
818- --intr=_<U+0008>C
819- Use _<U+0008>C instead of ^X to interrupt a read.
820- --line-num-width=_<U+0008>N
821- Set the width of the -N line number field to _<U+0008>N characters.
822- --modelines=_<U+0008>N
823- Read _<U+0008>N lines from the input file and look for vim modelines.
824- --mouse
825- Enable mouse input.
826- --no-keypad
827- Don't send termcap keypad init/deinit strings.
828- --no-histdups
829- Remove duplicates from command history.
830- --no-number-headers
831- Don't give line numbers to header lines.
832- --no-search-headers
833- Don't search in header lines or columns.
834- --no-vbell
835- Disable the terminal's visual bell.
836- --redraw-on-quit
837- Redraw final screen when quitting.
838- --rscroll=_<U+0008>C
839- Set the character used to mark truncated lines.
840- --save-marks
841- Retain marks across invocations of less.
842- --search-options=[EFKNRW-]
843- Set default options for every search.
844- --show-preproc-errors
845- Display a message if preprocessor exits with an error status.
846- --proc-backspace
847- Process backspaces for bold/underline.
848- --SPECIAL-BACKSPACE
849- Treat backspaces as control characters.
850- --proc-return
851- Delete carriage returns before newline.
852- --SPECIAL-RETURN
853- Treat carriage returns as control characters.
854- --proc-tab
855- Expand tabs to spaces.
856- --SPECIAL-TAB
857- Treat tabs as control characters.
858- --status-col-width=_<U+0008>N
859- Set the width of the -J status column to _<U+0008>N characters.
860- --status-line
861- Highlight or color the entire line containing a mark.
862- --use-backslash
863- Subsequent options use backslash as escape char.
864- --use-color
865- Enables colored text.
866- --wheel-lines=_<U+0008>N
867- Each click of the mouse wheel moves _<U+0008>N lines.
868- --wordwrap
869- Wrap lines at spaces.
870-
871-
872- ---------------------------------------------------------------------------
873-
874- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
875-
876- These keys can be used to edit text being entered
877- on the "command line" at the bottom of the screen.
878-
879- RightArrow ..................... ESC-l ... Move cursor right one character.
880- LeftArrow ...................... ESC-h ... Move cursor left one character.
881- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
882- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
883- HOME ........................... ESC-0 ... Move cursor to start of line.
884- END ............................ ESC-$ ... Move cursor to end of line.
885- BACKSPACE ................................ Delete char to left of cursor.
886- DELETE ......................... ESC-x ... Delete char under cursor.
887- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
888- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
889- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
890- UpArrow ........................ ESC-k ... Retrieve previous command line.
891- DownArrow ...................... ESC-j ... Retrieve next command line.
892- TAB ...................................... Complete filename & cycle.
893- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
894- ctrl-L ................................... Complete filename, list all.
895-
896- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
897-
898- Commands marked with * may be preceded by a number, _<U+0008>N.
899- Notes in parentheses indicate the behavior if _<U+0008>N is given.
900- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
901-
902- h H Display this help.
903- q :q Q :Q ZZ Exit.
904- ---------------------------------------------------------------------------
905-
906- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
907-
908- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
909- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
910- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
911- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
912- z * Forward one window (and set window to _<U+0008>N).
913- w * Backward one window (and set window to _<U+0008>N).
914- ESC-SPACE * Forward one window, but don't stop at end-of-file.
915- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
916- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
917- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
918- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
919- ESC-} ^RightArrow Right to last column displayed.
920- ESC-{ ^LeftArrow Left to first column.
921- F Forward forever; like "tail -f".
922- ESC-F Like F but stop when search pattern is found.
923- r ^R ^L Repaint screen.
924- R Repaint screen, discarding buffered input.
925- ---------------------------------------------------
926- Default "window" is the screen height.
927- Default "half-window" is half of the screen height.
928- ---------------------------------------------------------------------------
929-
930- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
931-
932- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
933- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
934- n * Repeat previous search (for _<U+0008>N-th occurrence).
935- N * Repeat previous search in reverse direction.
936- ESC-n * Repeat previous search, spanning files.
937- ESC-N * Repeat previous search, reverse dir. & spanning files.
938- ESC-u Undo (toggle) search highlighting.
939- ESC-U Clear search highlighting.
940- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
941- ---------------------------------------------------
942- A search pattern may begin with one or more of:
943- ^N or ! Search for NON-matching lines.
944- ^E or * Search multiple files (pass thru END OF FILE).
945- ^F or @ Start search at FIRST file (for /) or last file (for ?).
946- ^K Highlight matches, but don't move (KEEP position).
947- ^R Don't use REGULAR EXPRESSIONS.
948- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
949- ^W WRAP search if no match found.
950- ---------------------------------------------------------------------------
951-
952- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
953-
954- g < ESC-< * Go to first line in file (or line _<U+0008>N).
955- G > ESC-> * Go to last line in file (or line _<U+0008>N).
956- p % * Go to beginning of file (or _<U+0008>N percent into file).
957- t * Go to the (_<U+0008>N-th) next tag.
958- T * Go to the (_<U+0008>N-th) previous tag.
959- { ( [ * Find close bracket } ) ].
960- } ) ] * Find open bracket { ( [.
961- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
962- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
963- ---------------------------------------------------
964- Each "find close bracket" command goes forward to the close bracket
965- matching the (_<U+0008>N-th) open bracket in the top line.
966- Each "find open bracket" command goes backward to the open bracket
967- matching the (_<U+0008>N-th) close bracket in the bottom line.
968-
969- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
970- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
971- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
972- '' Go to the previous position.
973- ^X^X Same as '.
974- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
975- ---------------------------------------------------
976- A mark is any upper-case or lower-case letter.
977- Certain marks are predefined:
978- ^ means beginning of the file
979- $ means end of the file
980- ---------------------------------------------------------------------------
981-
982- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
983-
984- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
985- ^X^V Same as :e.
986- :n * Examine the (_<U+0008>N-th) next file from the command line.
987- :p * Examine the (_<U+0008>N-th) previous file from the command line.
988- :x * Examine the first (or _<U+0008>N-th) file from the command line.
989- :d Delete the current file from the command line list.
990- = ^G :f Print current file name.
991- ---------------------------------------------------------------------------
992-
993- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
994-
995- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
996- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
997- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
998- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
999- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
1000-
1001- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
1002- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
1003- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
1004- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
1005- v Edit the current file with $VISUAL or $EDITOR.
1006- V Print version number of "less".
1007- ---------------------------------------------------------------------------
1008-
1009- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
1010-
1011- Most options may be changed either on the command line,
1012- or from within less by using the - or -- command.
1013- Options may be given in one of two forms: either a single
1014- character preceded by a -, or a name preceded by --.
1015-
1016- -? ........ --help
1017- Display help (from command line).
1018- -a ........ --search-skip-screen
1019- Search skips current screen.
1020- -A ........ --SEARCH-SKIP-SCREEN
1021- Search starts just after target line.
1022- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
1023- Number of buffers.
1024- -B ........ --auto-buffers
1025- Don't automatically allocate buffers for pipes.
1026- -c ........ --clear-screen
1027- Repaint by clearing rather than scrolling.
1028- -d ........ --dumb
1029- Dumb terminal.
1030- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
1031- Set screen colors.
1032- -e -E .... --quit-at-eof --QUIT-AT-EOF
1033- Quit at end of file.
1034- -f ........ --force
1035- Force open non-regular files.
1036- -F ........ --quit-if-one-screen
1037- Quit if entire file fits on first screen.
1038- -g ........ --hilite-search
1039- Highlight only last match for searches.
1040- -G ........ --HILITE-SEARCH
1041- Don't highlight any matches for searches.
1042- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
1043- Backward scroll limit.
1044- -i ........ --ignore-case
1045- Ignore case in searches that do not contain uppercase.
1046- -I ........ --IGNORE-CASE
1047- Ignore case in all searches.
1048- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
1049- Screen position of target lines.
1050- -J ........ --status-column
1051- Display a status column at left edge of screen.
1052- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
1053- Use a lesskey file.
1054- -K ........ --quit-on-intr
1055- Exit less in response to ctrl-C.
1056- -L ........ --no-lessopen
1057- Ignore the LESSOPEN environment variable.
1058- -m -M .... --long-prompt --LONG-PROMPT
1059- Set prompt style.
1060- -n ......... --line-numbers
1061- Suppress line numbers in prompts and messages.
1062- -N ......... --LINE-NUMBERS
1063- Display line number at start of each line.
1064- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
1065- Copy to log file (standard input only).
1066- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
1067- Copy to log file (unconditionally overwrite).
1068- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
1069- Start at pattern (from command line).
1070- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
1071- Define new prompt.
1072- -q -Q .... --quiet --QUIET --silent --SILENT
1073- Quiet the terminal bell.
1074- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
1075- Output "raw" control characters.
1076- -s ........ --squeeze-blank-lines
1077- Squeeze multiple blank lines.
1078- -S ........ --chop-long-lines
1079- Chop (truncate) long lines rather than wrapping.
1080- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
1081- Find a tag.
1082- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
1083- Use an alternate tags file.
1084- -u -U .... --underline-special --UNDERLINE-SPECIAL
1085- Change handling of backspaces, tabs and carriage returns.
1086- -V ........ --version
1087- Display the version number of "less".
1088- -w ........ --hilite-unread
1089- Highlight first new line after forward-screen.
1090- -W ........ --HILITE-UNREAD
1091- Highlight first new line after any forward movement.
1092- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
1093- Set tab stops.
1094- -X ........ --no-init
1095- Don't use termcap init/deinit strings.
1096- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
1097- Forward scroll limit.
1098- -z [_<U+0008>N] .... --window=[_<U+0008>N]
1099- Set size of window.
1100- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
1101- Set shell quote characters.
1102- -~ ........ --tilde
1103- Don't display tildes after end of file.
1104- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
1105- Set horizontal scroll amount (0 = one half screen width).
1106- --exit-follow-on-close
1107- Exit F command on a pipe when writer closes pipe.
1108- --file-size
1109- Automatically determine the size of the input file.
1110- --follow-name
1111- The F command changes files if the input file is renamed.
1112- --header=[_<U+0008>N[,_<U+0008>M]]
1113- Use N lines and M columns to display file headers.
1114- --incsearch
1115- Search file as each pattern character is typed in.
1116- --intr=_<U+0008>C
1117- Use _<U+0008>C instead of ^X to interrupt a read.
1118- --line-num-width=_<U+0008>N
1119- Set the width of the -N line number field to _<U+0008>N characters.
1120- --modelines=_<U+0008>N
1121- Read _<U+0008>N lines from the input file and look for vim modelines.
1122- --mouse
1123- Enable mouse input.
1124- --no-keypad
1125- Don't send termcap keypad init/deinit strings.
1126- --no-histdups
1127- Remove duplicates from command history.
1128- --no-number-headers
1129- Don't give line numbers to header lines.
1130- --no-search-headers
1131- Don't search in header lines or columns.
1132- --no-vbell
1133- Disable the terminal's visual bell.
1134- --redraw-on-quit
1135- Redraw final screen when quitting.
1136- --rscroll=_<U+0008>C
1137- Set the character used to mark truncated lines.
1138- --save-marks
1139- Retain marks across invocations of less.
1140- --search-options=[EFKNRW-]
1141- Set default options for every search.
1142- --show-preproc-errors
1143- Display a message if preprocessor exits with an error status.
1144- --proc-backspace
1145- Process backspaces for bold/underline.
1146- --SPECIAL-BACKSPACE
1147- Treat backspaces as control characters.
1148- --proc-return
1149- Delete carriage returns before newline.
1150- --SPECIAL-RETURN
1151- Treat carriage returns as control characters.
1152- --proc-tab
1153- Expand tabs to spaces.
1154- --SPECIAL-TAB
1155- Treat tabs as control characters.
1156- --status-col-width=_<U+0008>N
1157- Set the width of the -J status column to _<U+0008>N characters.
1158- --status-line
1159- Highlight or color the entire line containing a mark.
1160- --use-backslash
1161- Subsequent options use backslash as escape char.
1162- --use-color
1163- Enables colored text.
1164- --wheel-lines=_<U+0008>N
1165- Each click of the mouse wheel moves _<U+0008>N lines.
1166- --wordwrap
1167- Wrap lines at spaces.
1168-
1169-
1170- ---------------------------------------------------------------------------
1171-
1172- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
1173-
1174- These keys can be used to edit text being entered
1175- on the "command line" at the bottom of the screen.
1176-
1177- RightArrow ..................... ESC-l ... Move cursor right one character.
1178- LeftArrow ...................... ESC-h ... Move cursor left one character.
1179- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
1180- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
1181- HOME ........................... ESC-0 ... Move cursor to start of line.
1182- END ............................ ESC-$ ... Move cursor to end of line.
1183- BACKSPACE ................................ Delete char to left of cursor.
1184- DELETE ......................... ESC-x ... Delete char under cursor.
1185- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
1186- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
1187- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
1188- UpArrow ........................ ESC-k ... Retrieve previous command line.
1189- DownArrow ...................... ESC-j ... Retrieve next command line.
1190- TAB ...................................... Complete filename & cycle.
1191- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
1192- ctrl-L ................................... Complete filename, list all.
@@ -1,1192 +0,0 @@
1-
2- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
3-
4- Commands marked with * may be preceded by a number, _<U+0008>N.
5- Notes in parentheses indicate the behavior if _<U+0008>N is given.
6- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
7-
8- h H Display this help.
9- q :q Q :Q ZZ Exit.
10- ---------------------------------------------------------------------------
11-
12- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
13-
14- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
15- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
16- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
17- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
18- z * Forward one window (and set window to _<U+0008>N).
19- w * Backward one window (and set window to _<U+0008>N).
20- ESC-SPACE * Forward one window, but don't stop at end-of-file.
21- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
22- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
23- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
24- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
25- ESC-} ^RightArrow Right to last column displayed.
26- ESC-{ ^LeftArrow Left to first column.
27- F Forward forever; like "tail -f".
28- ESC-F Like F but stop when search pattern is found.
29- r ^R ^L Repaint screen.
30- R Repaint screen, discarding buffered input.
31- ---------------------------------------------------
32- Default "window" is the screen height.
33- Default "half-window" is half of the screen height.
34- ---------------------------------------------------------------------------
35-
36- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
37-
38- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
39- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
40- n * Repeat previous search (for _<U+0008>N-th occurrence).
41- N * Repeat previous search in reverse direction.
42- ESC-n * Repeat previous search, spanning files.
43- ESC-N * Repeat previous search, reverse dir. & spanning files.
44- ESC-u Undo (toggle) search highlighting.
45- ESC-U Clear search highlighting.
46- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
47- ---------------------------------------------------
48- A search pattern may begin with one or more of:
49- ^N or ! Search for NON-matching lines.
50- ^E or * Search multiple files (pass thru END OF FILE).
51- ^F or @ Start search at FIRST file (for /) or last file (for ?).
52- ^K Highlight matches, but don't move (KEEP position).
53- ^R Don't use REGULAR EXPRESSIONS.
54- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
55- ^W WRAP search if no match found.
56- ---------------------------------------------------------------------------
57-
58- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
59-
60- g < ESC-< * Go to first line in file (or line _<U+0008>N).
61- G > ESC-> * Go to last line in file (or line _<U+0008>N).
62- p % * Go to beginning of file (or _<U+0008>N percent into file).
63- t * Go to the (_<U+0008>N-th) next tag.
64- T * Go to the (_<U+0008>N-th) previous tag.
65- { ( [ * Find close bracket } ) ].
66- } ) ] * Find open bracket { ( [.
67- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
68- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
69- ---------------------------------------------------
70- Each "find close bracket" command goes forward to the close bracket
71- matching the (_<U+0008>N-th) open bracket in the top line.
72- Each "find open bracket" command goes backward to the open bracket
73- matching the (_<U+0008>N-th) close bracket in the bottom line.
74-
75- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
76- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
77- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
78- '' Go to the previous position.
79- ^X^X Same as '.
80- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
81- ---------------------------------------------------
82- A mark is any upper-case or lower-case letter.
83- Certain marks are predefined:
84- ^ means beginning of the file
85- $ means end of the file
86- ---------------------------------------------------------------------------
87-
88- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
89-
90- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
91- ^X^V Same as :e.
92- :n * Examine the (_<U+0008>N-th) next file from the command line.
93- :p * Examine the (_<U+0008>N-th) previous file from the command line.
94- :x * Examine the first (or _<U+0008>N-th) file from the command line.
95- :d Delete the current file from the command line list.
96- = ^G :f Print current file name.
97- ---------------------------------------------------------------------------
98-
99- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
100-
101- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
102- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
103- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
104- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
105- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
106-
107- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
108- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
109- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
110- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
111- v Edit the current file with $VISUAL or $EDITOR.
112- V Print version number of "less".
113- ---------------------------------------------------------------------------
114-
115- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
116-
117- Most options may be changed either on the command line,
118- or from within less by using the - or -- command.
119- Options may be given in one of two forms: either a single
120- character preceded by a -, or a name preceded by --.
121-
122- -? ........ --help
123- Display help (from command line).
124- -a ........ --search-skip-screen
125- Search skips current screen.
126- -A ........ --SEARCH-SKIP-SCREEN
127- Search starts just after target line.
128- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
129- Number of buffers.
130- -B ........ --auto-buffers
131- Don't automatically allocate buffers for pipes.
132- -c ........ --clear-screen
133- Repaint by clearing rather than scrolling.
134- -d ........ --dumb
135- Dumb terminal.
136- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
137- Set screen colors.
138- -e -E .... --quit-at-eof --QUIT-AT-EOF
139- Quit at end of file.
140- -f ........ --force
141- Force open non-regular files.
142- -F ........ --quit-if-one-screen
143- Quit if entire file fits on first screen.
144- -g ........ --hilite-search
145- Highlight only last match for searches.
146- -G ........ --HILITE-SEARCH
147- Don't highlight any matches for searches.
148- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
149- Backward scroll limit.
150- -i ........ --ignore-case
151- Ignore case in searches that do not contain uppercase.
152- -I ........ --IGNORE-CASE
153- Ignore case in all searches.
154- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
155- Screen position of target lines.
156- -J ........ --status-column
157- Display a status column at left edge of screen.
158- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
159- Use a lesskey file.
160- -K ........ --quit-on-intr
161- Exit less in response to ctrl-C.
162- -L ........ --no-lessopen
163- Ignore the LESSOPEN environment variable.
164- -m -M .... --long-prompt --LONG-PROMPT
165- Set prompt style.
166- -n ......... --line-numbers
167- Suppress line numbers in prompts and messages.
168- -N ......... --LINE-NUMBERS
169- Display line number at start of each line.
170- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
171- Copy to log file (standard input only).
172- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
173- Copy to log file (unconditionally overwrite).
174- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
175- Start at pattern (from command line).
176- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
177- Define new prompt.
178- -q -Q .... --quiet --QUIET --silent --SILENT
179- Quiet the terminal bell.
180- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
181- Output "raw" control characters.
182- -s ........ --squeeze-blank-lines
183- Squeeze multiple blank lines.
184- -S ........ --chop-long-lines
185- Chop (truncate) long lines rather than wrapping.
186- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
187- Find a tag.
188- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
189- Use an alternate tags file.
190- -u -U .... --underline-special --UNDERLINE-SPECIAL
191- Change handling of backspaces, tabs and carriage returns.
192- -V ........ --version
193- Display the version number of "less".
194- -w ........ --hilite-unread
195- Highlight first new line after forward-screen.
196- -W ........ --HILITE-UNREAD
197- Highlight first new line after any forward movement.
198- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
199- Set tab stops.
200- -X ........ --no-init
201- Don't use termcap init/deinit strings.
202- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
203- Forward scroll limit.
204- -z [_<U+0008>N] .... --window=[_<U+0008>N]
205- Set size of window.
206- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
207- Set shell quote characters.
208- -~ ........ --tilde
209- Don't display tildes after end of file.
210- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
211- Set horizontal scroll amount (0 = one half screen width).
212- --exit-follow-on-close
213- Exit F command on a pipe when writer closes pipe.
214- --file-size
215- Automatically determine the size of the input file.
216- --follow-name
217- The F command changes files if the input file is renamed.
218- --header=[_<U+0008>N[,_<U+0008>M]]
219- Use N lines and M columns to display file headers.
220- --incsearch
221- Search file as each pattern character is typed in.
222- --intr=_<U+0008>C
223- Use _<U+0008>C instead of ^X to interrupt a read.
224- --line-num-width=_<U+0008>N
225- Set the width of the -N line number field to _<U+0008>N characters.
226- --modelines=_<U+0008>N
227- Read _<U+0008>N lines from the input file and look for vim modelines.
228- --mouse
229- Enable mouse input.
230- --no-keypad
231- Don't send termcap keypad init/deinit strings.
232- --no-histdups
233- Remove duplicates from command history.
234- --no-number-headers
235- Don't give line numbers to header lines.
236- --no-search-headers
237- Don't search in header lines or columns.
238- --no-vbell
239- Disable the terminal's visual bell.
240- --redraw-on-quit
241- Redraw final screen when quitting.
242- --rscroll=_<U+0008>C
243- Set the character used to mark truncated lines.
244- --save-marks
245- Retain marks across invocations of less.
246- --search-options=[EFKNRW-]
247- Set default options for every search.
248- --show-preproc-errors
249- Display a message if preprocessor exits with an error status.
250- --proc-backspace
251- Process backspaces for bold/underline.
252- --SPECIAL-BACKSPACE
253- Treat backspaces as control characters.
254- --proc-return
255- Delete carriage returns before newline.
256- --SPECIAL-RETURN
257- Treat carriage returns as control characters.
258- --proc-tab
259- Expand tabs to spaces.
260- --SPECIAL-TAB
261- Treat tabs as control characters.
262- --status-col-width=_<U+0008>N
263- Set the width of the -J status column to _<U+0008>N characters.
264- --status-line
265- Highlight or color the entire line containing a mark.
266- --use-backslash
267- Subsequent options use backslash as escape char.
268- --use-color
269- Enables colored text.
270- --wheel-lines=_<U+0008>N
271- Each click of the mouse wheel moves _<U+0008>N lines.
272- --wordwrap
273- Wrap lines at spaces.
274-
275-
276- ---------------------------------------------------------------------------
277-
278- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
279-
280- These keys can be used to edit text being entered
281- on the "command line" at the bottom of the screen.
282-
283- RightArrow ..................... ESC-l ... Move cursor right one character.
284- LeftArrow ...................... ESC-h ... Move cursor left one character.
285- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
286- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
287- HOME ........................... ESC-0 ... Move cursor to start of line.
288- END ............................ ESC-$ ... Move cursor to end of line.
289- BACKSPACE ................................ Delete char to left of cursor.
290- DELETE ......................... ESC-x ... Delete char under cursor.
291- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
292- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
293- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
294- UpArrow ........................ ESC-k ... Retrieve previous command line.
295- DownArrow ...................... ESC-j ... Retrieve next command line.
296- TAB ...................................... Complete filename & cycle.
297- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
298- ctrl-L ................................... Complete filename, list all.
299-
300- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
301-
302- Commands marked with * may be preceded by a number, _<U+0008>N.
303- Notes in parentheses indicate the behavior if _<U+0008>N is given.
304- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
305-
306- h H Display this help.
307- q :q Q :Q ZZ Exit.
308- ---------------------------------------------------------------------------
309-
310- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
311-
312- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
313- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
314- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
315- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
316- z * Forward one window (and set window to _<U+0008>N).
317- w * Backward one window (and set window to _<U+0008>N).
318- ESC-SPACE * Forward one window, but don't stop at end-of-file.
319- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
320- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
321- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
322- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
323- ESC-} ^RightArrow Right to last column displayed.
324- ESC-{ ^LeftArrow Left to first column.
325- F Forward forever; like "tail -f".
326- ESC-F Like F but stop when search pattern is found.
327- r ^R ^L Repaint screen.
328- R Repaint screen, discarding buffered input.
329- ---------------------------------------------------
330- Default "window" is the screen height.
331- Default "half-window" is half of the screen height.
332- ---------------------------------------------------------------------------
333-
334- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
335-
336- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
337- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
338- n * Repeat previous search (for _<U+0008>N-th occurrence).
339- N * Repeat previous search in reverse direction.
340- ESC-n * Repeat previous search, spanning files.
341- ESC-N * Repeat previous search, reverse dir. & spanning files.
342- ESC-u Undo (toggle) search highlighting.
343- ESC-U Clear search highlighting.
344- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
345- ---------------------------------------------------
346- A search pattern may begin with one or more of:
347- ^N or ! Search for NON-matching lines.
348- ^E or * Search multiple files (pass thru END OF FILE).
349- ^F or @ Start search at FIRST file (for /) or last file (for ?).
350- ^K Highlight matches, but don't move (KEEP position).
351- ^R Don't use REGULAR EXPRESSIONS.
352- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
353- ^W WRAP search if no match found.
354- ---------------------------------------------------------------------------
355-
356- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
357-
358- g < ESC-< * Go to first line in file (or line _<U+0008>N).
359- G > ESC-> * Go to last line in file (or line _<U+0008>N).
360- p % * Go to beginning of file (or _<U+0008>N percent into file).
361- t * Go to the (_<U+0008>N-th) next tag.
362- T * Go to the (_<U+0008>N-th) previous tag.
363- { ( [ * Find close bracket } ) ].
364- } ) ] * Find open bracket { ( [.
365- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
366- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
367- ---------------------------------------------------
368- Each "find close bracket" command goes forward to the close bracket
369- matching the (_<U+0008>N-th) open bracket in the top line.
370- Each "find open bracket" command goes backward to the open bracket
371- matching the (_<U+0008>N-th) close bracket in the bottom line.
372-
373- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
374- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
375- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
376- '' Go to the previous position.
377- ^X^X Same as '.
378- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
379- ---------------------------------------------------
380- A mark is any upper-case or lower-case letter.
381- Certain marks are predefined:
382- ^ means beginning of the file
383- $ means end of the file
384- ---------------------------------------------------------------------------
385-
386- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
387-
388- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
389- ^X^V Same as :e.
390- :n * Examine the (_<U+0008>N-th) next file from the command line.
391- :p * Examine the (_<U+0008>N-th) previous file from the command line.
392- :x * Examine the first (or _<U+0008>N-th) file from the command line.
393- :d Delete the current file from the command line list.
394- = ^G :f Print current file name.
395- ---------------------------------------------------------------------------
396-
397- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
398-
399- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
400- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
401- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
402- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
403- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
404-
405- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
406- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
407- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
408- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
409- v Edit the current file with $VISUAL or $EDITOR.
410- V Print version number of "less".
411- ---------------------------------------------------------------------------
412-
413- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
414-
415- Most options may be changed either on the command line,
416- or from within less by using the - or -- command.
417- Options may be given in one of two forms: either a single
418- character preceded by a -, or a name preceded by --.
419-
420- -? ........ --help
421- Display help (from command line).
422- -a ........ --search-skip-screen
423- Search skips current screen.
424- -A ........ --SEARCH-SKIP-SCREEN
425- Search starts just after target line.
426- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
427- Number of buffers.
428- -B ........ --auto-buffers
429- Don't automatically allocate buffers for pipes.
430- -c ........ --clear-screen
431- Repaint by clearing rather than scrolling.
432- -d ........ --dumb
433- Dumb terminal.
434- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
435- Set screen colors.
436- -e -E .... --quit-at-eof --QUIT-AT-EOF
437- Quit at end of file.
438- -f ........ --force
439- Force open non-regular files.
440- -F ........ --quit-if-one-screen
441- Quit if entire file fits on first screen.
442- -g ........ --hilite-search
443- Highlight only last match for searches.
444- -G ........ --HILITE-SEARCH
445- Don't highlight any matches for searches.
446- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
447- Backward scroll limit.
448- -i ........ --ignore-case
449- Ignore case in searches that do not contain uppercase.
450- -I ........ --IGNORE-CASE
451- Ignore case in all searches.
452- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
453- Screen position of target lines.
454- -J ........ --status-column
455- Display a status column at left edge of screen.
456- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
457- Use a lesskey file.
458- -K ........ --quit-on-intr
459- Exit less in response to ctrl-C.
460- -L ........ --no-lessopen
461- Ignore the LESSOPEN environment variable.
462- -m -M .... --long-prompt --LONG-PROMPT
463- Set prompt style.
464- -n ......... --line-numbers
465- Suppress line numbers in prompts and messages.
466- -N ......... --LINE-NUMBERS
467- Display line number at start of each line.
468- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
469- Copy to log file (standard input only).
470- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
471- Copy to log file (unconditionally overwrite).
472- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
473- Start at pattern (from command line).
474- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
475- Define new prompt.
476- -q -Q .... --quiet --QUIET --silent --SILENT
477- Quiet the terminal bell.
478- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
479- Output "raw" control characters.
480- -s ........ --squeeze-blank-lines
481- Squeeze multiple blank lines.
482- -S ........ --chop-long-lines
483- Chop (truncate) long lines rather than wrapping.
484- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
485- Find a tag.
486- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
487- Use an alternate tags file.
488- -u -U .... --underline-special --UNDERLINE-SPECIAL
489- Change handling of backspaces, tabs and carriage returns.
490- -V ........ --version
491- Display the version number of "less".
492- -w ........ --hilite-unread
493- Highlight first new line after forward-screen.
494- -W ........ --HILITE-UNREAD
495- Highlight first new line after any forward movement.
496- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
497- Set tab stops.
498- -X ........ --no-init
499- Don't use termcap init/deinit strings.
500- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
501- Forward scroll limit.
502- -z [_<U+0008>N] .... --window=[_<U+0008>N]
503- Set size of window.
504- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
505- Set shell quote characters.
506- -~ ........ --tilde
507- Don't display tildes after end of file.
508- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
509- Set horizontal scroll amount (0 = one half screen width).
510- --exit-follow-on-close
511- Exit F command on a pipe when writer closes pipe.
512- --file-size
513- Automatically determine the size of the input file.
514- --follow-name
515- The F command changes files if the input file is renamed.
516- --header=[_<U+0008>N[,_<U+0008>M]]
517- Use N lines and M columns to display file headers.
518- --incsearch
519- Search file as each pattern character is typed in.
520- --intr=_<U+0008>C
521- Use _<U+0008>C instead of ^X to interrupt a read.
522- --line-num-width=_<U+0008>N
523- Set the width of the -N line number field to _<U+0008>N characters.
524- --modelines=_<U+0008>N
525- Read _<U+0008>N lines from the input file and look for vim modelines.
526- --mouse
527- Enable mouse input.
528- --no-keypad
529- Don't send termcap keypad init/deinit strings.
530- --no-histdups
531- Remove duplicates from command history.
532- --no-number-headers
533- Don't give line numbers to header lines.
534- --no-search-headers
535- Don't search in header lines or columns.
536- --no-vbell
537- Disable the terminal's visual bell.
538- --redraw-on-quit
539- Redraw final screen when quitting.
540- --rscroll=_<U+0008>C
541- Set the character used to mark truncated lines.
542- --save-marks
543- Retain marks across invocations of less.
544- --search-options=[EFKNRW-]
545- Set default options for every search.
546- --show-preproc-errors
547- Display a message if preprocessor exits with an error status.
548- --proc-backspace
549- Process backspaces for bold/underline.
550- --SPECIAL-BACKSPACE
551- Treat backspaces as control characters.
552- --proc-return
553- Delete carriage returns before newline.
554- --SPECIAL-RETURN
555- Treat carriage returns as control characters.
556- --proc-tab
557- Expand tabs to spaces.
558- --SPECIAL-TAB
559- Treat tabs as control characters.
560- --status-col-width=_<U+0008>N
561- Set the width of the -J status column to _<U+0008>N characters.
562- --status-line
563- Highlight or color the entire line containing a mark.
564- --use-backslash
565- Subsequent options use backslash as escape char.
566- --use-color
567- Enables colored text.
568- --wheel-lines=_<U+0008>N
569- Each click of the mouse wheel moves _<U+0008>N lines.
570- --wordwrap
571- Wrap lines at spaces.
572-
573-
574- ---------------------------------------------------------------------------
575-
576- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
577-
578- These keys can be used to edit text being entered
579- on the "command line" at the bottom of the screen.
580-
581- RightArrow ..................... ESC-l ... Move cursor right one character.
582- LeftArrow ...................... ESC-h ... Move cursor left one character.
583- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
584- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
585- HOME ........................... ESC-0 ... Move cursor to start of line.
586- END ............................ ESC-$ ... Move cursor to end of line.
587- BACKSPACE ................................ Delete char to left of cursor.
588- DELETE ......................... ESC-x ... Delete char under cursor.
589- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
590- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
591- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
592- UpArrow ........................ ESC-k ... Retrieve previous command line.
593- DownArrow ...................... ESC-j ... Retrieve next command line.
594- TAB ...................................... Complete filename & cycle.
595- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
596- ctrl-L ................................... Complete filename, list all.
597-
598- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
599-
600- Commands marked with * may be preceded by a number, _<U+0008>N.
601- Notes in parentheses indicate the behavior if _<U+0008>N is given.
602- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
603-
604- h H Display this help.
605- q :q Q :Q ZZ Exit.
606- ---------------------------------------------------------------------------
607-
608- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
609-
610- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
611- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
612- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
613- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
614- z * Forward one window (and set window to _<U+0008>N).
615- w * Backward one window (and set window to _<U+0008>N).
616- ESC-SPACE * Forward one window, but don't stop at end-of-file.
617- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
618- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
619- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
620- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
621- ESC-} ^RightArrow Right to last column displayed.
622- ESC-{ ^LeftArrow Left to first column.
623- F Forward forever; like "tail -f".
624- ESC-F Like F but stop when search pattern is found.
625- r ^R ^L Repaint screen.
626- R Repaint screen, discarding buffered input.
627- ---------------------------------------------------
628- Default "window" is the screen height.
629- Default "half-window" is half of the screen height.
630- ---------------------------------------------------------------------------
631-
632- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
633-
634- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
635- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
636- n * Repeat previous search (for _<U+0008>N-th occurrence).
637- N * Repeat previous search in reverse direction.
638- ESC-n * Repeat previous search, spanning files.
639- ESC-N * Repeat previous search, reverse dir. & spanning files.
640- ESC-u Undo (toggle) search highlighting.
641- ESC-U Clear search highlighting.
642- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
643- ---------------------------------------------------
644- A search pattern may begin with one or more of:
645- ^N or ! Search for NON-matching lines.
646- ^E or * Search multiple files (pass thru END OF FILE).
647- ^F or @ Start search at FIRST file (for /) or last file (for ?).
648- ^K Highlight matches, but don't move (KEEP position).
649- ^R Don't use REGULAR EXPRESSIONS.
650- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
651- ^W WRAP search if no match found.
652- ---------------------------------------------------------------------------
653-
654- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
655-
656- g < ESC-< * Go to first line in file (or line _<U+0008>N).
657- G > ESC-> * Go to last line in file (or line _<U+0008>N).
658- p % * Go to beginning of file (or _<U+0008>N percent into file).
659- t * Go to the (_<U+0008>N-th) next tag.
660- T * Go to the (_<U+0008>N-th) previous tag.
661- { ( [ * Find close bracket } ) ].
662- } ) ] * Find open bracket { ( [.
663- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
664- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
665- ---------------------------------------------------
666- Each "find close bracket" command goes forward to the close bracket
667- matching the (_<U+0008>N-th) open bracket in the top line.
668- Each "find open bracket" command goes backward to the open bracket
669- matching the (_<U+0008>N-th) close bracket in the bottom line.
670-
671- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
672- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
673- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
674- '' Go to the previous position.
675- ^X^X Same as '.
676- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
677- ---------------------------------------------------
678- A mark is any upper-case or lower-case letter.
679- Certain marks are predefined:
680- ^ means beginning of the file
681- $ means end of the file
682- ---------------------------------------------------------------------------
683-
684- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
685-
686- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
687- ^X^V Same as :e.
688- :n * Examine the (_<U+0008>N-th) next file from the command line.
689- :p * Examine the (_<U+0008>N-th) previous file from the command line.
690- :x * Examine the first (or _<U+0008>N-th) file from the command line.
691- :d Delete the current file from the command line list.
692- = ^G :f Print current file name.
693- ---------------------------------------------------------------------------
694-
695- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
696-
697- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
698- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
699- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
700- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
701- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
702-
703- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
704- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
705- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
706- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
707- v Edit the current file with $VISUAL or $EDITOR.
708- V Print version number of "less".
709- ---------------------------------------------------------------------------
710-
711- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
712-
713- Most options may be changed either on the command line,
714- or from within less by using the - or -- command.
715- Options may be given in one of two forms: either a single
716- character preceded by a -, or a name preceded by --.
717-
718- -? ........ --help
719- Display help (from command line).
720- -a ........ --search-skip-screen
721- Search skips current screen.
722- -A ........ --SEARCH-SKIP-SCREEN
723- Search starts just after target line.
724- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
725- Number of buffers.
726- -B ........ --auto-buffers
727- Don't automatically allocate buffers for pipes.
728- -c ........ --clear-screen
729- Repaint by clearing rather than scrolling.
730- -d ........ --dumb
731- Dumb terminal.
732- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
733- Set screen colors.
734- -e -E .... --quit-at-eof --QUIT-AT-EOF
735- Quit at end of file.
736- -f ........ --force
737- Force open non-regular files.
738- -F ........ --quit-if-one-screen
739- Quit if entire file fits on first screen.
740- -g ........ --hilite-search
741- Highlight only last match for searches.
742- -G ........ --HILITE-SEARCH
743- Don't highlight any matches for searches.
744- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
745- Backward scroll limit.
746- -i ........ --ignore-case
747- Ignore case in searches that do not contain uppercase.
748- -I ........ --IGNORE-CASE
749- Ignore case in all searches.
750- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
751- Screen position of target lines.
752- -J ........ --status-column
753- Display a status column at left edge of screen.
754- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
755- Use a lesskey file.
756- -K ........ --quit-on-intr
757- Exit less in response to ctrl-C.
758- -L ........ --no-lessopen
759- Ignore the LESSOPEN environment variable.
760- -m -M .... --long-prompt --LONG-PROMPT
761- Set prompt style.
762- -n ......... --line-numbers
763- Suppress line numbers in prompts and messages.
764- -N ......... --LINE-NUMBERS
765- Display line number at start of each line.
766- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
767- Copy to log file (standard input only).
768- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
769- Copy to log file (unconditionally overwrite).
770- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
771- Start at pattern (from command line).
772- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
773- Define new prompt.
774- -q -Q .... --quiet --QUIET --silent --SILENT
775- Quiet the terminal bell.
776- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
777- Output "raw" control characters.
778- -s ........ --squeeze-blank-lines
779- Squeeze multiple blank lines.
780- -S ........ --chop-long-lines
781- Chop (truncate) long lines rather than wrapping.
782- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
783- Find a tag.
784- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
785- Use an alternate tags file.
786- -u -U .... --underline-special --UNDERLINE-SPECIAL
787- Change handling of backspaces, tabs and carriage returns.
788- -V ........ --version
789- Display the version number of "less".
790- -w ........ --hilite-unread
791- Highlight first new line after forward-screen.
792- -W ........ --HILITE-UNREAD
793- Highlight first new line after any forward movement.
794- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
795- Set tab stops.
796- -X ........ --no-init
797- Don't use termcap init/deinit strings.
798- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
799- Forward scroll limit.
800- -z [_<U+0008>N] .... --window=[_<U+0008>N]
801- Set size of window.
802- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
803- Set shell quote characters.
804- -~ ........ --tilde
805- Don't display tildes after end of file.
806- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
807- Set horizontal scroll amount (0 = one half screen width).
808- --exit-follow-on-close
809- Exit F command on a pipe when writer closes pipe.
810- --file-size
811- Automatically determine the size of the input file.
812- --follow-name
813- The F command changes files if the input file is renamed.
814- --header=[_<U+0008>N[,_<U+0008>M]]
815- Use N lines and M columns to display file headers.
816- --incsearch
817- Search file as each pattern character is typed in.
818- --intr=_<U+0008>C
819- Use _<U+0008>C instead of ^X to interrupt a read.
820- --line-num-width=_<U+0008>N
821- Set the width of the -N line number field to _<U+0008>N characters.
822- --modelines=_<U+0008>N
823- Read _<U+0008>N lines from the input file and look for vim modelines.
824- --mouse
825- Enable mouse input.
826- --no-keypad
827- Don't send termcap keypad init/deinit strings.
828- --no-histdups
829- Remove duplicates from command history.
830- --no-number-headers
831- Don't give line numbers to header lines.
832- --no-search-headers
833- Don't search in header lines or columns.
834- --no-vbell
835- Disable the terminal's visual bell.
836- --redraw-on-quit
837- Redraw final screen when quitting.
838- --rscroll=_<U+0008>C
839- Set the character used to mark truncated lines.
840- --save-marks
841- Retain marks across invocations of less.
842- --search-options=[EFKNRW-]
843- Set default options for every search.
844- --show-preproc-errors
845- Display a message if preprocessor exits with an error status.
846- --proc-backspace
847- Process backspaces for bold/underline.
848- --SPECIAL-BACKSPACE
849- Treat backspaces as control characters.
850- --proc-return
851- Delete carriage returns before newline.
852- --SPECIAL-RETURN
853- Treat carriage returns as control characters.
854- --proc-tab
855- Expand tabs to spaces.
856- --SPECIAL-TAB
857- Treat tabs as control characters.
858- --status-col-width=_<U+0008>N
859- Set the width of the -J status column to _<U+0008>N characters.
860- --status-line
861- Highlight or color the entire line containing a mark.
862- --use-backslash
863- Subsequent options use backslash as escape char.
864- --use-color
865- Enables colored text.
866- --wheel-lines=_<U+0008>N
867- Each click of the mouse wheel moves _<U+0008>N lines.
868- --wordwrap
869- Wrap lines at spaces.
870-
871-
872- ---------------------------------------------------------------------------
873-
874- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
875-
876- These keys can be used to edit text being entered
877- on the "command line" at the bottom of the screen.
878-
879- RightArrow ..................... ESC-l ... Move cursor right one character.
880- LeftArrow ...................... ESC-h ... Move cursor left one character.
881- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
882- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
883- HOME ........................... ESC-0 ... Move cursor to start of line.
884- END ............................ ESC-$ ... Move cursor to end of line.
885- BACKSPACE ................................ Delete char to left of cursor.
886- DELETE ......................... ESC-x ... Delete char under cursor.
887- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
888- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
889- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
890- UpArrow ........................ ESC-k ... Retrieve previous command line.
891- DownArrow ...................... ESC-j ... Retrieve next command line.
892- TAB ...................................... Complete filename & cycle.
893- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
894- ctrl-L ................................... Complete filename, list all.
895-
896- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
897-
898- Commands marked with * may be preceded by a number, _<U+0008>N.
899- Notes in parentheses indicate the behavior if _<U+0008>N is given.
900- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
901-
902- h H Display this help.
903- q :q Q :Q ZZ Exit.
904- ---------------------------------------------------------------------------
905-
906- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
907-
908- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
909- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
910- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
911- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
912- z * Forward one window (and set window to _<U+0008>N).
913- w * Backward one window (and set window to _<U+0008>N).
914- ESC-SPACE * Forward one window, but don't stop at end-of-file.
915- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
916- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
917- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
918- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
919- ESC-} ^RightArrow Right to last column displayed.
920- ESC-{ ^LeftArrow Left to first column.
921- F Forward forever; like "tail -f".
922- ESC-F Like F but stop when search pattern is found.
923- r ^R ^L Repaint screen.
924- R Repaint screen, discarding buffered input.
925- ---------------------------------------------------
926- Default "window" is the screen height.
927- Default "half-window" is half of the screen height.
928- ---------------------------------------------------------------------------
929-
930- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
931-
932- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
933- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
934- n * Repeat previous search (for _<U+0008>N-th occurrence).
935- N * Repeat previous search in reverse direction.
936- ESC-n * Repeat previous search, spanning files.
937- ESC-N * Repeat previous search, reverse dir. & spanning files.
938- ESC-u Undo (toggle) search highlighting.
939- ESC-U Clear search highlighting.
940- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
941- ---------------------------------------------------
942- A search pattern may begin with one or more of:
943- ^N or ! Search for NON-matching lines.
944- ^E or * Search multiple files (pass thru END OF FILE).
945- ^F or @ Start search at FIRST file (for /) or last file (for ?).
946- ^K Highlight matches, but don't move (KEEP position).
947- ^R Don't use REGULAR EXPRESSIONS.
948- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
949- ^W WRAP search if no match found.
950- ---------------------------------------------------------------------------
951-
952- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
953-
954- g < ESC-< * Go to first line in file (or line _<U+0008>N).
955- G > ESC-> * Go to last line in file (or line _<U+0008>N).
956- p % * Go to beginning of file (or _<U+0008>N percent into file).
957- t * Go to the (_<U+0008>N-th) next tag.
958- T * Go to the (_<U+0008>N-th) previous tag.
959- { ( [ * Find close bracket } ) ].
960- } ) ] * Find open bracket { ( [.
961- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
962- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
963- ---------------------------------------------------
964- Each "find close bracket" command goes forward to the close bracket
965- matching the (_<U+0008>N-th) open bracket in the top line.
966- Each "find open bracket" command goes backward to the open bracket
967- matching the (_<U+0008>N-th) close bracket in the bottom line.
968-
969- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
970- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
971- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
972- '' Go to the previous position.
973- ^X^X Same as '.
974- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
975- ---------------------------------------------------
976- A mark is any upper-case or lower-case letter.
977- Certain marks are predefined:
978- ^ means beginning of the file
979- $ means end of the file
980- ---------------------------------------------------------------------------
981-
982- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
983-
984- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
985- ^X^V Same as :e.
986- :n * Examine the (_<U+0008>N-th) next file from the command line.
987- :p * Examine the (_<U+0008>N-th) previous file from the command line.
988- :x * Examine the first (or _<U+0008>N-th) file from the command line.
989- :d Delete the current file from the command line list.
990- = ^G :f Print current file name.
991- ---------------------------------------------------------------------------
992-
993- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
994-
995- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
996- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
997- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
998- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
999- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
1000-
1001- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
1002- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
1003- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
1004- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
1005- v Edit the current file with $VISUAL or $EDITOR.
1006- V Print version number of "less".
1007- ---------------------------------------------------------------------------
1008-
1009- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
1010-
1011- Most options may be changed either on the command line,
1012- or from within less by using the - or -- command.
1013- Options may be given in one of two forms: either a single
1014- character preceded by a -, or a name preceded by --.
1015-
1016- -? ........ --help
1017- Display help (from command line).
1018- -a ........ --search-skip-screen
1019- Search skips current screen.
1020- -A ........ --SEARCH-SKIP-SCREEN
1021- Search starts just after target line.
1022- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
1023- Number of buffers.
1024- -B ........ --auto-buffers
1025- Don't automatically allocate buffers for pipes.
1026- -c ........ --clear-screen
1027- Repaint by clearing rather than scrolling.
1028- -d ........ --dumb
1029- Dumb terminal.
1030- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
1031- Set screen colors.
1032- -e -E .... --quit-at-eof --QUIT-AT-EOF
1033- Quit at end of file.
1034- -f ........ --force
1035- Force open non-regular files.
1036- -F ........ --quit-if-one-screen
1037- Quit if entire file fits on first screen.
1038- -g ........ --hilite-search
1039- Highlight only last match for searches.
1040- -G ........ --HILITE-SEARCH
1041- Don't highlight any matches for searches.
1042- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
1043- Backward scroll limit.
1044- -i ........ --ignore-case
1045- Ignore case in searches that do not contain uppercase.
1046- -I ........ --IGNORE-CASE
1047- Ignore case in all searches.
1048- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
1049- Screen position of target lines.
1050- -J ........ --status-column
1051- Display a status column at left edge of screen.
1052- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
1053- Use a lesskey file.
1054- -K ........ --quit-on-intr
1055- Exit less in response to ctrl-C.
1056- -L ........ --no-lessopen
1057- Ignore the LESSOPEN environment variable.
1058- -m -M .... --long-prompt --LONG-PROMPT
1059- Set prompt style.
1060- -n ......... --line-numbers
1061- Suppress line numbers in prompts and messages.
1062- -N ......... --LINE-NUMBERS
1063- Display line number at start of each line.
1064- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
1065- Copy to log file (standard input only).
1066- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
1067- Copy to log file (unconditionally overwrite).
1068- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
1069- Start at pattern (from command line).
1070- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
1071- Define new prompt.
1072- -q -Q .... --quiet --QUIET --silent --SILENT
1073- Quiet the terminal bell.
1074- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
1075- Output "raw" control characters.
1076- -s ........ --squeeze-blank-lines
1077- Squeeze multiple blank lines.
1078- -S ........ --chop-long-lines
1079- Chop (truncate) long lines rather than wrapping.
1080- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
1081- Find a tag.
1082- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
1083- Use an alternate tags file.
1084- -u -U .... --underline-special --UNDERLINE-SPECIAL
1085- Change handling of backspaces, tabs and carriage returns.
1086- -V ........ --version
1087- Display the version number of "less".
1088- -w ........ --hilite-unread
1089- Highlight first new line after forward-screen.
1090- -W ........ --HILITE-UNREAD
1091- Highlight first new line after any forward movement.
1092- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
1093- Set tab stops.
1094- -X ........ --no-init
1095- Don't use termcap init/deinit strings.
1096- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
1097- Forward scroll limit.
1098- -z [_<U+0008>N] .... --window=[_<U+0008>N]
1099- Set size of window.
1100- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
1101- Set shell quote characters.
1102- -~ ........ --tilde
1103- Don't display tildes after end of file.
1104- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
1105- Set horizontal scroll amount (0 = one half screen width).
1106- --exit-follow-on-close
1107- Exit F command on a pipe when writer closes pipe.
1108- --file-size
1109- Automatically determine the size of the input file.
1110- --follow-name
1111- The F command changes files if the input file is renamed.
1112- --header=[_<U+0008>N[,_<U+0008>M]]
1113- Use N lines and M columns to display file headers.
1114- --incsearch
1115- Search file as each pattern character is typed in.
1116- --intr=_<U+0008>C
1117- Use _<U+0008>C instead of ^X to interrupt a read.
1118- --line-num-width=_<U+0008>N
1119- Set the width of the -N line number field to _<U+0008>N characters.
1120- --modelines=_<U+0008>N
1121- Read _<U+0008>N lines from the input file and look for vim modelines.
1122- --mouse
1123- Enable mouse input.
1124- --no-keypad
1125- Don't send termcap keypad init/deinit strings.
1126- --no-histdups
1127- Remove duplicates from command history.
1128- --no-number-headers
1129- Don't give line numbers to header lines.
1130- --no-search-headers
1131- Don't search in header lines or columns.
1132- --no-vbell
1133- Disable the terminal's visual bell.
1134- --redraw-on-quit
1135- Redraw final screen when quitting.
1136- --rscroll=_<U+0008>C
1137- Set the character used to mark truncated lines.
1138- --save-marks
1139- Retain marks across invocations of less.
1140- --search-options=[EFKNRW-]
1141- Set default options for every search.
1142- --show-preproc-errors
1143- Display a message if preprocessor exits with an error status.
1144- --proc-backspace
1145- Process backspaces for bold/underline.
1146- --SPECIAL-BACKSPACE
1147- Treat backspaces as control characters.
1148- --proc-return
1149- Delete carriage returns before newline.
1150- --SPECIAL-RETURN
1151- Treat carriage returns as control characters.
1152- --proc-tab
1153- Expand tabs to spaces.
1154- --SPECIAL-TAB
1155- Treat tabs as control characters.
1156- --status-col-width=_<U+0008>N
1157- Set the width of the -J status column to _<U+0008>N characters.
1158- --status-line
1159- Highlight or color the entire line containing a mark.
1160- --use-backslash
1161- Subsequent options use backslash as escape char.
1162- --use-color
1163- Enables colored text.
1164- --wheel-lines=_<U+0008>N
1165- Each click of the mouse wheel moves _<U+0008>N lines.
1166- --wordwrap
1167- Wrap lines at spaces.
1168-
1169-
1170- ---------------------------------------------------------------------------
1171-
1172- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
1173-
1174- These keys can be used to edit text being entered
1175- on the "command line" at the bottom of the screen.
1176-
1177- RightArrow ..................... ESC-l ... Move cursor right one character.
1178- LeftArrow ...................... ESC-h ... Move cursor left one character.
1179- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
1180- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
1181- HOME ........................... ESC-0 ... Move cursor to start of line.
1182- END ............................ ESC-$ ... Move cursor to end of line.
1183- BACKSPACE ................................ Delete char to left of cursor.
1184- DELETE ......................... ESC-x ... Delete char under cursor.
1185- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
1186- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
1187- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
1188- UpArrow ........................ ESC-k ... Retrieve previous command line.
1189- DownArrow ...................... ESC-j ... Retrieve next command line.
1190- TAB ...................................... Complete filename & cycle.
1191- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
1192- ctrl-L ................................... Complete filename, list all.
D s=flex flex-col items-center bg-gordonmascot-hblue rounded-md +0 -298
@@ -1,298 +0,0 @@
1-
2- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
3-
4- Commands marked with * may be preceded by a number, _<U+0008>N.
5- Notes in parentheses indicate the behavior if _<U+0008>N is given.
6- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
7-
8- h H Display this help.
9- q :q Q :Q ZZ Exit.
10- ---------------------------------------------------------------------------
11-
12- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
13-
14- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
15- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
16- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
17- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
18- z * Forward one window (and set window to _<U+0008>N).
19- w * Backward one window (and set window to _<U+0008>N).
20- ESC-SPACE * Forward one window, but don't stop at end-of-file.
21- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
22- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
23- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
24- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
25- ESC-} ^RightArrow Right to last column displayed.
26- ESC-{ ^LeftArrow Left to first column.
27- F Forward forever; like "tail -f".
28- ESC-F Like F but stop when search pattern is found.
29- r ^R ^L Repaint screen.
30- R Repaint screen, discarding buffered input.
31- ---------------------------------------------------
32- Default "window" is the screen height.
33- Default "half-window" is half of the screen height.
34- ---------------------------------------------------------------------------
35-
36- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
37-
38- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
39- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
40- n * Repeat previous search (for _<U+0008>N-th occurrence).
41- N * Repeat previous search in reverse direction.
42- ESC-n * Repeat previous search, spanning files.
43- ESC-N * Repeat previous search, reverse dir. & spanning files.
44- ESC-u Undo (toggle) search highlighting.
45- ESC-U Clear search highlighting.
46- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
47- ---------------------------------------------------
48- A search pattern may begin with one or more of:
49- ^N or ! Search for NON-matching lines.
50- ^E or * Search multiple files (pass thru END OF FILE).
51- ^F or @ Start search at FIRST file (for /) or last file (for ?).
52- ^K Highlight matches, but don't move (KEEP position).
53- ^R Don't use REGULAR EXPRESSIONS.
54- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
55- ^W WRAP search if no match found.
56- ---------------------------------------------------------------------------
57-
58- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
59-
60- g < ESC-< * Go to first line in file (or line _<U+0008>N).
61- G > ESC-> * Go to last line in file (or line _<U+0008>N).
62- p % * Go to beginning of file (or _<U+0008>N percent into file).
63- t * Go to the (_<U+0008>N-th) next tag.
64- T * Go to the (_<U+0008>N-th) previous tag.
65- { ( [ * Find close bracket } ) ].
66- } ) ] * Find open bracket { ( [.
67- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
68- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
69- ---------------------------------------------------
70- Each "find close bracket" command goes forward to the close bracket
71- matching the (_<U+0008>N-th) open bracket in the top line.
72- Each "find open bracket" command goes backward to the open bracket
73- matching the (_<U+0008>N-th) close bracket in the bottom line.
74-
75- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
76- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
77- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
78- '' Go to the previous position.
79- ^X^X Same as '.
80- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
81- ---------------------------------------------------
82- A mark is any upper-case or lower-case letter.
83- Certain marks are predefined:
84- ^ means beginning of the file
85- $ means end of the file
86- ---------------------------------------------------------------------------
87-
88- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
89-
90- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
91- ^X^V Same as :e.
92- :n * Examine the (_<U+0008>N-th) next file from the command line.
93- :p * Examine the (_<U+0008>N-th) previous file from the command line.
94- :x * Examine the first (or _<U+0008>N-th) file from the command line.
95- :d Delete the current file from the command line list.
96- = ^G :f Print current file name.
97- ---------------------------------------------------------------------------
98-
99- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
100-
101- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
102- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
103- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
104- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
105- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
106-
107- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
108- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
109- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
110- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
111- v Edit the current file with $VISUAL or $EDITOR.
112- V Print version number of "less".
113- ---------------------------------------------------------------------------
114-
115- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
116-
117- Most options may be changed either on the command line,
118- or from within less by using the - or -- command.
119- Options may be given in one of two forms: either a single
120- character preceded by a -, or a name preceded by --.
121-
122- -? ........ --help
123- Display help (from command line).
124- -a ........ --search-skip-screen
125- Search skips current screen.
126- -A ........ --SEARCH-SKIP-SCREEN
127- Search starts just after target line.
128- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
129- Number of buffers.
130- -B ........ --auto-buffers
131- Don't automatically allocate buffers for pipes.
132- -c ........ --clear-screen
133- Repaint by clearing rather than scrolling.
134- -d ........ --dumb
135- Dumb terminal.
136- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
137- Set screen colors.
138- -e -E .... --quit-at-eof --QUIT-AT-EOF
139- Quit at end of file.
140- -f ........ --force
141- Force open non-regular files.
142- -F ........ --quit-if-one-screen
143- Quit if entire file fits on first screen.
144- -g ........ --hilite-search
145- Highlight only last match for searches.
146- -G ........ --HILITE-SEARCH
147- Don't highlight any matches for searches.
148- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
149- Backward scroll limit.
150- -i ........ --ignore-case
151- Ignore case in searches that do not contain uppercase.
152- -I ........ --IGNORE-CASE
153- Ignore case in all searches.
154- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
155- Screen position of target lines.
156- -J ........ --status-column
157- Display a status column at left edge of screen.
158- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
159- Use a lesskey file.
160- -K ........ --quit-on-intr
161- Exit less in response to ctrl-C.
162- -L ........ --no-lessopen
163- Ignore the LESSOPEN environment variable.
164- -m -M .... --long-prompt --LONG-PROMPT
165- Set prompt style.
166- -n ......... --line-numbers
167- Suppress line numbers in prompts and messages.
168- -N ......... --LINE-NUMBERS
169- Display line number at start of each line.
170- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
171- Copy to log file (standard input only).
172- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
173- Copy to log file (unconditionally overwrite).
174- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
175- Start at pattern (from command line).
176- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
177- Define new prompt.
178- -q -Q .... --quiet --QUIET --silent --SILENT
179- Quiet the terminal bell.
180- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
181- Output "raw" control characters.
182- -s ........ --squeeze-blank-lines
183- Squeeze multiple blank lines.
184- -S ........ --chop-long-lines
185- Chop (truncate) long lines rather than wrapping.
186- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
187- Find a tag.
188- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
189- Use an alternate tags file.
190- -u -U .... --underline-special --UNDERLINE-SPECIAL
191- Change handling of backspaces, tabs and carriage returns.
192- -V ........ --version
193- Display the version number of "less".
194- -w ........ --hilite-unread
195- Highlight first new line after forward-screen.
196- -W ........ --HILITE-UNREAD
197- Highlight first new line after any forward movement.
198- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
199- Set tab stops.
200- -X ........ --no-init
201- Don't use termcap init/deinit strings.
202- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
203- Forward scroll limit.
204- -z [_<U+0008>N] .... --window=[_<U+0008>N]
205- Set size of window.
206- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
207- Set shell quote characters.
208- -~ ........ --tilde
209- Don't display tildes after end of file.
210- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
211- Set horizontal scroll amount (0 = one half screen width).
212- --exit-follow-on-close
213- Exit F command on a pipe when writer closes pipe.
214- --file-size
215- Automatically determine the size of the input file.
216- --follow-name
217- The F command changes files if the input file is renamed.
218- --header=[_<U+0008>N[,_<U+0008>M]]
219- Use N lines and M columns to display file headers.
220- --incsearch
221- Search file as each pattern character is typed in.
222- --intr=_<U+0008>C
223- Use _<U+0008>C instead of ^X to interrupt a read.
224- --line-num-width=_<U+0008>N
225- Set the width of the -N line number field to _<U+0008>N characters.
226- --modelines=_<U+0008>N
227- Read _<U+0008>N lines from the input file and look for vim modelines.
228- --mouse
229- Enable mouse input.
230- --no-keypad
231- Don't send termcap keypad init/deinit strings.
232- --no-histdups
233- Remove duplicates from command history.
234- --no-number-headers
235- Don't give line numbers to header lines.
236- --no-search-headers
237- Don't search in header lines or columns.
238- --no-vbell
239- Disable the terminal's visual bell.
240- --redraw-on-quit
241- Redraw final screen when quitting.
242- --rscroll=_<U+0008>C
243- Set the character used to mark truncated lines.
244- --save-marks
245- Retain marks across invocations of less.
246- --search-options=[EFKNRW-]
247- Set default options for every search.
248- --show-preproc-errors
249- Display a message if preprocessor exits with an error status.
250- --proc-backspace
251- Process backspaces for bold/underline.
252- --SPECIAL-BACKSPACE
253- Treat backspaces as control characters.
254- --proc-return
255- Delete carriage returns before newline.
256- --SPECIAL-RETURN
257- Treat carriage returns as control characters.
258- --proc-tab
259- Expand tabs to spaces.
260- --SPECIAL-TAB
261- Treat tabs as control characters.
262- --status-col-width=_<U+0008>N
263- Set the width of the -J status column to _<U+0008>N characters.
264- --status-line
265- Highlight or color the entire line containing a mark.
266- --use-backslash
267- Subsequent options use backslash as escape char.
268- --use-color
269- Enables colored text.
270- --wheel-lines=_<U+0008>N
271- Each click of the mouse wheel moves _<U+0008>N lines.
272- --wordwrap
273- Wrap lines at spaces.
274-
275-
276- ---------------------------------------------------------------------------
277-
278- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
279-
280- These keys can be used to edit text being entered
281- on the "command line" at the bottom of the screen.
282-
283- RightArrow ..................... ESC-l ... Move cursor right one character.
284- LeftArrow ...................... ESC-h ... Move cursor left one character.
285- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
286- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
287- HOME ........................... ESC-0 ... Move cursor to start of line.
288- END ............................ ESC-$ ... Move cursor to end of line.
289- BACKSPACE ................................ Delete char to left of cursor.
290- DELETE ......................... ESC-x ... Delete char under cursor.
291- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
292- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
293- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
294- UpArrow ........................ ESC-k ... Retrieve previous command line.
295- DownArrow ...................... ESC-j ... Retrieve next command line.
296- TAB ...................................... Complete filename & cycle.
297- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
298- ctrl-L ................................... Complete filename, list all.
@@ -1,298 +0,0 @@
1-
2- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
3-
4- Commands marked with * may be preceded by a number, _<U+0008>N.
5- Notes in parentheses indicate the behavior if _<U+0008>N is given.
6- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
7-
8- h H Display this help.
9- q :q Q :Q ZZ Exit.
10- ---------------------------------------------------------------------------
11-
12- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
13-
14- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
15- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
16- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
17- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
18- z * Forward one window (and set window to _<U+0008>N).
19- w * Backward one window (and set window to _<U+0008>N).
20- ESC-SPACE * Forward one window, but don't stop at end-of-file.
21- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
22- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
23- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
24- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
25- ESC-} ^RightArrow Right to last column displayed.
26- ESC-{ ^LeftArrow Left to first column.
27- F Forward forever; like "tail -f".
28- ESC-F Like F but stop when search pattern is found.
29- r ^R ^L Repaint screen.
30- R Repaint screen, discarding buffered input.
31- ---------------------------------------------------
32- Default "window" is the screen height.
33- Default "half-window" is half of the screen height.
34- ---------------------------------------------------------------------------
35-
36- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
37-
38- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
39- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
40- n * Repeat previous search (for _<U+0008>N-th occurrence).
41- N * Repeat previous search in reverse direction.
42- ESC-n * Repeat previous search, spanning files.
43- ESC-N * Repeat previous search, reverse dir. & spanning files.
44- ESC-u Undo (toggle) search highlighting.
45- ESC-U Clear search highlighting.
46- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
47- ---------------------------------------------------
48- A search pattern may begin with one or more of:
49- ^N or ! Search for NON-matching lines.
50- ^E or * Search multiple files (pass thru END OF FILE).
51- ^F or @ Start search at FIRST file (for /) or last file (for ?).
52- ^K Highlight matches, but don't move (KEEP position).
53- ^R Don't use REGULAR EXPRESSIONS.
54- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
55- ^W WRAP search if no match found.
56- ---------------------------------------------------------------------------
57-
58- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
59-
60- g < ESC-< * Go to first line in file (or line _<U+0008>N).
61- G > ESC-> * Go to last line in file (or line _<U+0008>N).
62- p % * Go to beginning of file (or _<U+0008>N percent into file).
63- t * Go to the (_<U+0008>N-th) next tag.
64- T * Go to the (_<U+0008>N-th) previous tag.
65- { ( [ * Find close bracket } ) ].
66- } ) ] * Find open bracket { ( [.
67- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
68- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
69- ---------------------------------------------------
70- Each "find close bracket" command goes forward to the close bracket
71- matching the (_<U+0008>N-th) open bracket in the top line.
72- Each "find open bracket" command goes backward to the open bracket
73- matching the (_<U+0008>N-th) close bracket in the bottom line.
74-
75- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
76- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
77- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
78- '' Go to the previous position.
79- ^X^X Same as '.
80- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
81- ---------------------------------------------------
82- A mark is any upper-case or lower-case letter.
83- Certain marks are predefined:
84- ^ means beginning of the file
85- $ means end of the file
86- ---------------------------------------------------------------------------
87-
88- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
89-
90- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
91- ^X^V Same as :e.
92- :n * Examine the (_<U+0008>N-th) next file from the command line.
93- :p * Examine the (_<U+0008>N-th) previous file from the command line.
94- :x * Examine the first (or _<U+0008>N-th) file from the command line.
95- :d Delete the current file from the command line list.
96- = ^G :f Print current file name.
97- ---------------------------------------------------------------------------
98-
99- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
100-
101- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
102- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
103- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
104- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
105- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
106-
107- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
108- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
109- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
110- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
111- v Edit the current file with $VISUAL or $EDITOR.
112- V Print version number of "less".
113- ---------------------------------------------------------------------------
114-
115- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
116-
117- Most options may be changed either on the command line,
118- or from within less by using the - or -- command.
119- Options may be given in one of two forms: either a single
120- character preceded by a -, or a name preceded by --.
121-
122- -? ........ --help
123- Display help (from command line).
124- -a ........ --search-skip-screen
125- Search skips current screen.
126- -A ........ --SEARCH-SKIP-SCREEN
127- Search starts just after target line.
128- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
129- Number of buffers.
130- -B ........ --auto-buffers
131- Don't automatically allocate buffers for pipes.
132- -c ........ --clear-screen
133- Repaint by clearing rather than scrolling.
134- -d ........ --dumb
135- Dumb terminal.
136- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
137- Set screen colors.
138- -e -E .... --quit-at-eof --QUIT-AT-EOF
139- Quit at end of file.
140- -f ........ --force
141- Force open non-regular files.
142- -F ........ --quit-if-one-screen
143- Quit if entire file fits on first screen.
144- -g ........ --hilite-search
145- Highlight only last match for searches.
146- -G ........ --HILITE-SEARCH
147- Don't highlight any matches for searches.
148- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
149- Backward scroll limit.
150- -i ........ --ignore-case
151- Ignore case in searches that do not contain uppercase.
152- -I ........ --IGNORE-CASE
153- Ignore case in all searches.
154- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
155- Screen position of target lines.
156- -J ........ --status-column
157- Display a status column at left edge of screen.
158- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
159- Use a lesskey file.
160- -K ........ --quit-on-intr
161- Exit less in response to ctrl-C.
162- -L ........ --no-lessopen
163- Ignore the LESSOPEN environment variable.
164- -m -M .... --long-prompt --LONG-PROMPT
165- Set prompt style.
166- -n ......... --line-numbers
167- Suppress line numbers in prompts and messages.
168- -N ......... --LINE-NUMBERS
169- Display line number at start of each line.
170- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
171- Copy to log file (standard input only).
172- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
173- Copy to log file (unconditionally overwrite).
174- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
175- Start at pattern (from command line).
176- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
177- Define new prompt.
178- -q -Q .... --quiet --QUIET --silent --SILENT
179- Quiet the terminal bell.
180- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
181- Output "raw" control characters.
182- -s ........ --squeeze-blank-lines
183- Squeeze multiple blank lines.
184- -S ........ --chop-long-lines
185- Chop (truncate) long lines rather than wrapping.
186- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
187- Find a tag.
188- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
189- Use an alternate tags file.
190- -u -U .... --underline-special --UNDERLINE-SPECIAL
191- Change handling of backspaces, tabs and carriage returns.
192- -V ........ --version
193- Display the version number of "less".
194- -w ........ --hilite-unread
195- Highlight first new line after forward-screen.
196- -W ........ --HILITE-UNREAD
197- Highlight first new line after any forward movement.
198- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
199- Set tab stops.
200- -X ........ --no-init
201- Don't use termcap init/deinit strings.
202- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
203- Forward scroll limit.
204- -z [_<U+0008>N] .... --window=[_<U+0008>N]
205- Set size of window.
206- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
207- Set shell quote characters.
208- -~ ........ --tilde
209- Don't display tildes after end of file.
210- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
211- Set horizontal scroll amount (0 = one half screen width).
212- --exit-follow-on-close
213- Exit F command on a pipe when writer closes pipe.
214- --file-size
215- Automatically determine the size of the input file.
216- --follow-name
217- The F command changes files if the input file is renamed.
218- --header=[_<U+0008>N[,_<U+0008>M]]
219- Use N lines and M columns to display file headers.
220- --incsearch
221- Search file as each pattern character is typed in.
222- --intr=_<U+0008>C
223- Use _<U+0008>C instead of ^X to interrupt a read.
224- --line-num-width=_<U+0008>N
225- Set the width of the -N line number field to _<U+0008>N characters.
226- --modelines=_<U+0008>N
227- Read _<U+0008>N lines from the input file and look for vim modelines.
228- --mouse
229- Enable mouse input.
230- --no-keypad
231- Don't send termcap keypad init/deinit strings.
232- --no-histdups
233- Remove duplicates from command history.
234- --no-number-headers
235- Don't give line numbers to header lines.
236- --no-search-headers
237- Don't search in header lines or columns.
238- --no-vbell
239- Disable the terminal's visual bell.
240- --redraw-on-quit
241- Redraw final screen when quitting.
242- --rscroll=_<U+0008>C
243- Set the character used to mark truncated lines.
244- --save-marks
245- Retain marks across invocations of less.
246- --search-options=[EFKNRW-]
247- Set default options for every search.
248- --show-preproc-errors
249- Display a message if preprocessor exits with an error status.
250- --proc-backspace
251- Process backspaces for bold/underline.
252- --SPECIAL-BACKSPACE
253- Treat backspaces as control characters.
254- --proc-return
255- Delete carriage returns before newline.
256- --SPECIAL-RETURN
257- Treat carriage returns as control characters.
258- --proc-tab
259- Expand tabs to spaces.
260- --SPECIAL-TAB
261- Treat tabs as control characters.
262- --status-col-width=_<U+0008>N
263- Set the width of the -J status column to _<U+0008>N characters.
264- --status-line
265- Highlight or color the entire line containing a mark.
266- --use-backslash
267- Subsequent options use backslash as escape char.
268- --use-color
269- Enables colored text.
270- --wheel-lines=_<U+0008>N
271- Each click of the mouse wheel moves _<U+0008>N lines.
272- --wordwrap
273- Wrap lines at spaces.
274-
275-
276- ---------------------------------------------------------------------------
277-
278- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
279-
280- These keys can be used to edit text being entered
281- on the "command line" at the bottom of the screen.
282-
283- RightArrow ..................... ESC-l ... Move cursor right one character.
284- LeftArrow ...................... ESC-h ... Move cursor left one character.
285- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
286- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
287- HOME ........................... ESC-0 ... Move cursor to start of line.
288- END ............................ ESC-$ ... Move cursor to end of line.
289- BACKSPACE ................................ Delete char to left of cursor.
290- DELETE ......................... ESC-x ... Delete char under cursor.
291- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
292- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
293- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
294- UpArrow ........................ ESC-k ... Retrieve previous command line.
295- DownArrow ...................... ESC-j ... Retrieve next command line.
296- TAB ...................................... Complete filename & cycle.
297- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
298- ctrl-L ................................... Complete filename, list all.
D s=w-full py-2 px-4 my-2 border border-gray-300 rounded-md +0 -298
@@ -1,298 +0,0 @@
1-
2- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
3-
4- Commands marked with * may be preceded by a number, _<U+0008>N.
5- Notes in parentheses indicate the behavior if _<U+0008>N is given.
6- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
7-
8- h H Display this help.
9- q :q Q :Q ZZ Exit.
10- ---------------------------------------------------------------------------
11-
12- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
13-
14- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
15- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
16- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
17- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
18- z * Forward one window (and set window to _<U+0008>N).
19- w * Backward one window (and set window to _<U+0008>N).
20- ESC-SPACE * Forward one window, but don't stop at end-of-file.
21- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
22- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
23- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
24- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
25- ESC-} ^RightArrow Right to last column displayed.
26- ESC-{ ^LeftArrow Left to first column.
27- F Forward forever; like "tail -f".
28- ESC-F Like F but stop when search pattern is found.
29- r ^R ^L Repaint screen.
30- R Repaint screen, discarding buffered input.
31- ---------------------------------------------------
32- Default "window" is the screen height.
33- Default "half-window" is half of the screen height.
34- ---------------------------------------------------------------------------
35-
36- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
37-
38- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
39- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
40- n * Repeat previous search (for _<U+0008>N-th occurrence).
41- N * Repeat previous search in reverse direction.
42- ESC-n * Repeat previous search, spanning files.
43- ESC-N * Repeat previous search, reverse dir. & spanning files.
44- ESC-u Undo (toggle) search highlighting.
45- ESC-U Clear search highlighting.
46- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
47- ---------------------------------------------------
48- A search pattern may begin with one or more of:
49- ^N or ! Search for NON-matching lines.
50- ^E or * Search multiple files (pass thru END OF FILE).
51- ^F or @ Start search at FIRST file (for /) or last file (for ?).
52- ^K Highlight matches, but don't move (KEEP position).
53- ^R Don't use REGULAR EXPRESSIONS.
54- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
55- ^W WRAP search if no match found.
56- ---------------------------------------------------------------------------
57-
58- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
59-
60- g < ESC-< * Go to first line in file (or line _<U+0008>N).
61- G > ESC-> * Go to last line in file (or line _<U+0008>N).
62- p % * Go to beginning of file (or _<U+0008>N percent into file).
63- t * Go to the (_<U+0008>N-th) next tag.
64- T * Go to the (_<U+0008>N-th) previous tag.
65- { ( [ * Find close bracket } ) ].
66- } ) ] * Find open bracket { ( [.
67- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
68- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
69- ---------------------------------------------------
70- Each "find close bracket" command goes forward to the close bracket
71- matching the (_<U+0008>N-th) open bracket in the top line.
72- Each "find open bracket" command goes backward to the open bracket
73- matching the (_<U+0008>N-th) close bracket in the bottom line.
74-
75- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
76- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
77- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
78- '' Go to the previous position.
79- ^X^X Same as '.
80- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
81- ---------------------------------------------------
82- A mark is any upper-case or lower-case letter.
83- Certain marks are predefined:
84- ^ means beginning of the file
85- $ means end of the file
86- ---------------------------------------------------------------------------
87-
88- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
89-
90- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
91- ^X^V Same as :e.
92- :n * Examine the (_<U+0008>N-th) next file from the command line.
93- :p * Examine the (_<U+0008>N-th) previous file from the command line.
94- :x * Examine the first (or _<U+0008>N-th) file from the command line.
95- :d Delete the current file from the command line list.
96- = ^G :f Print current file name.
97- ---------------------------------------------------------------------------
98-
99- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
100-
101- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
102- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
103- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
104- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
105- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
106-
107- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
108- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
109- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
110- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
111- v Edit the current file with $VISUAL or $EDITOR.
112- V Print version number of "less".
113- ---------------------------------------------------------------------------
114-
115- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
116-
117- Most options may be changed either on the command line,
118- or from within less by using the - or -- command.
119- Options may be given in one of two forms: either a single
120- character preceded by a -, or a name preceded by --.
121-
122- -? ........ --help
123- Display help (from command line).
124- -a ........ --search-skip-screen
125- Search skips current screen.
126- -A ........ --SEARCH-SKIP-SCREEN
127- Search starts just after target line.
128- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
129- Number of buffers.
130- -B ........ --auto-buffers
131- Don't automatically allocate buffers for pipes.
132- -c ........ --clear-screen
133- Repaint by clearing rather than scrolling.
134- -d ........ --dumb
135- Dumb terminal.
136- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
137- Set screen colors.
138- -e -E .... --quit-at-eof --QUIT-AT-EOF
139- Quit at end of file.
140- -f ........ --force
141- Force open non-regular files.
142- -F ........ --quit-if-one-screen
143- Quit if entire file fits on first screen.
144- -g ........ --hilite-search
145- Highlight only last match for searches.
146- -G ........ --HILITE-SEARCH
147- Don't highlight any matches for searches.
148- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
149- Backward scroll limit.
150- -i ........ --ignore-case
151- Ignore case in searches that do not contain uppercase.
152- -I ........ --IGNORE-CASE
153- Ignore case in all searches.
154- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
155- Screen position of target lines.
156- -J ........ --status-column
157- Display a status column at left edge of screen.
158- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
159- Use a lesskey file.
160- -K ........ --quit-on-intr
161- Exit less in response to ctrl-C.
162- -L ........ --no-lessopen
163- Ignore the LESSOPEN environment variable.
164- -m -M .... --long-prompt --LONG-PROMPT
165- Set prompt style.
166- -n ......... --line-numbers
167- Suppress line numbers in prompts and messages.
168- -N ......... --LINE-NUMBERS
169- Display line number at start of each line.
170- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
171- Copy to log file (standard input only).
172- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
173- Copy to log file (unconditionally overwrite).
174- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
175- Start at pattern (from command line).
176- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
177- Define new prompt.
178- -q -Q .... --quiet --QUIET --silent --SILENT
179- Quiet the terminal bell.
180- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
181- Output "raw" control characters.
182- -s ........ --squeeze-blank-lines
183- Squeeze multiple blank lines.
184- -S ........ --chop-long-lines
185- Chop (truncate) long lines rather than wrapping.
186- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
187- Find a tag.
188- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
189- Use an alternate tags file.
190- -u -U .... --underline-special --UNDERLINE-SPECIAL
191- Change handling of backspaces, tabs and carriage returns.
192- -V ........ --version
193- Display the version number of "less".
194- -w ........ --hilite-unread
195- Highlight first new line after forward-screen.
196- -W ........ --HILITE-UNREAD
197- Highlight first new line after any forward movement.
198- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
199- Set tab stops.
200- -X ........ --no-init
201- Don't use termcap init/deinit strings.
202- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
203- Forward scroll limit.
204- -z [_<U+0008>N] .... --window=[_<U+0008>N]
205- Set size of window.
206- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
207- Set shell quote characters.
208- -~ ........ --tilde
209- Don't display tildes after end of file.
210- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
211- Set horizontal scroll amount (0 = one half screen width).
212- --exit-follow-on-close
213- Exit F command on a pipe when writer closes pipe.
214- --file-size
215- Automatically determine the size of the input file.
216- --follow-name
217- The F command changes files if the input file is renamed.
218- --header=[_<U+0008>N[,_<U+0008>M]]
219- Use N lines and M columns to display file headers.
220- --incsearch
221- Search file as each pattern character is typed in.
222- --intr=_<U+0008>C
223- Use _<U+0008>C instead of ^X to interrupt a read.
224- --line-num-width=_<U+0008>N
225- Set the width of the -N line number field to _<U+0008>N characters.
226- --modelines=_<U+0008>N
227- Read _<U+0008>N lines from the input file and look for vim modelines.
228- --mouse
229- Enable mouse input.
230- --no-keypad
231- Don't send termcap keypad init/deinit strings.
232- --no-histdups
233- Remove duplicates from command history.
234- --no-number-headers
235- Don't give line numbers to header lines.
236- --no-search-headers
237- Don't search in header lines or columns.
238- --no-vbell
239- Disable the terminal's visual bell.
240- --redraw-on-quit
241- Redraw final screen when quitting.
242- --rscroll=_<U+0008>C
243- Set the character used to mark truncated lines.
244- --save-marks
245- Retain marks across invocations of less.
246- --search-options=[EFKNRW-]
247- Set default options for every search.
248- --show-preproc-errors
249- Display a message if preprocessor exits with an error status.
250- --proc-backspace
251- Process backspaces for bold/underline.
252- --SPECIAL-BACKSPACE
253- Treat backspaces as control characters.
254- --proc-return
255- Delete carriage returns before newline.
256- --SPECIAL-RETURN
257- Treat carriage returns as control characters.
258- --proc-tab
259- Expand tabs to spaces.
260- --SPECIAL-TAB
261- Treat tabs as control characters.
262- --status-col-width=_<U+0008>N
263- Set the width of the -J status column to _<U+0008>N characters.
264- --status-line
265- Highlight or color the entire line containing a mark.
266- --use-backslash
267- Subsequent options use backslash as escape char.
268- --use-color
269- Enables colored text.
270- --wheel-lines=_<U+0008>N
271- Each click of the mouse wheel moves _<U+0008>N lines.
272- --wordwrap
273- Wrap lines at spaces.
274-
275-
276- ---------------------------------------------------------------------------
277-
278- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
279-
280- These keys can be used to edit text being entered
281- on the "command line" at the bottom of the screen.
282-
283- RightArrow ..................... ESC-l ... Move cursor right one character.
284- LeftArrow ...................... ESC-h ... Move cursor left one character.
285- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
286- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
287- HOME ........................... ESC-0 ... Move cursor to start of line.
288- END ............................ ESC-$ ... Move cursor to end of line.
289- BACKSPACE ................................ Delete char to left of cursor.
290- DELETE ......................... ESC-x ... Delete char under cursor.
291- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
292- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
293- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
294- UpArrow ........................ ESC-k ... Retrieve previous command line.
295- DownArrow ...................... ESC-j ... Retrieve next command line.
296- TAB ...................................... Complete filename & cycle.
297- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
298- ctrl-L ................................... Complete filename, list all.
@@ -1,298 +0,0 @@
1-
2- S<U+0008>SU<U+0008>UM<U+0008>MM<U+0008>MA<U+0008>AR<U+0008>RY<U+0008>Y O<U+0008>OF<U+0008>F L<U+0008>LE<U+0008>ES<U+0008>SS<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
3-
4- Commands marked with * may be preceded by a number, _<U+0008>N.
5- Notes in parentheses indicate the behavior if _<U+0008>N is given.
6- A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
7-
8- h H Display this help.
9- q :q Q :Q ZZ Exit.
10- ---------------------------------------------------------------------------
11-
12- M<U+0008>MO<U+0008>OV<U+0008>VI<U+0008>IN<U+0008>NG<U+0008>G
13-
14- e ^E j ^N CR * Forward one line (or _<U+0008>N lines).
15- y ^Y k ^K ^P * Backward one line (or _<U+0008>N lines).
16- f ^F ^V SPACE * Forward one window (or _<U+0008>N lines).
17- b ^B ESC-v * Backward one window (or _<U+0008>N lines).
18- z * Forward one window (and set window to _<U+0008>N).
19- w * Backward one window (and set window to _<U+0008>N).
20- ESC-SPACE * Forward one window, but don't stop at end-of-file.
21- d ^D * Forward one half-window (and set half-window to _<U+0008>N).
22- u ^U * Backward one half-window (and set half-window to _<U+0008>N).
23- ESC-) RightArrow * Right one half screen width (or _<U+0008>N positions).
24- ESC-( LeftArrow * Left one half screen width (or _<U+0008>N positions).
25- ESC-} ^RightArrow Right to last column displayed.
26- ESC-{ ^LeftArrow Left to first column.
27- F Forward forever; like "tail -f".
28- ESC-F Like F but stop when search pattern is found.
29- r ^R ^L Repaint screen.
30- R Repaint screen, discarding buffered input.
31- ---------------------------------------------------
32- Default "window" is the screen height.
33- Default "half-window" is half of the screen height.
34- ---------------------------------------------------------------------------
35-
36- S<U+0008>SE<U+0008>EA<U+0008>AR<U+0008>RC<U+0008>CH<U+0008>HI<U+0008>IN<U+0008>NG<U+0008>G
37-
38- /_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search forward for (_<U+0008>N-th) matching line.
39- ?_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Search backward for (_<U+0008>N-th) matching line.
40- n * Repeat previous search (for _<U+0008>N-th occurrence).
41- N * Repeat previous search in reverse direction.
42- ESC-n * Repeat previous search, spanning files.
43- ESC-N * Repeat previous search, reverse dir. & spanning files.
44- ESC-u Undo (toggle) search highlighting.
45- ESC-U Clear search highlighting.
46- &_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n * Display only matching lines.
47- ---------------------------------------------------
48- A search pattern may begin with one or more of:
49- ^N or ! Search for NON-matching lines.
50- ^E or * Search multiple files (pass thru END OF FILE).
51- ^F or @ Start search at FIRST file (for /) or last file (for ?).
52- ^K Highlight matches, but don't move (KEEP position).
53- ^R Don't use REGULAR EXPRESSIONS.
54- ^S _<U+0008>n Search for match in _<U+0008>n-th parenthesized subpattern.
55- ^W WRAP search if no match found.
56- ---------------------------------------------------------------------------
57-
58- J<U+0008>JU<U+0008>UM<U+0008>MP<U+0008>PI<U+0008>IN<U+0008>NG<U+0008>G
59-
60- g < ESC-< * Go to first line in file (or line _<U+0008>N).
61- G > ESC-> * Go to last line in file (or line _<U+0008>N).
62- p % * Go to beginning of file (or _<U+0008>N percent into file).
63- t * Go to the (_<U+0008>N-th) next tag.
64- T * Go to the (_<U+0008>N-th) previous tag.
65- { ( [ * Find close bracket } ) ].
66- } ) ] * Find open bracket { ( [.
67- ESC-^F _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find close bracket _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>>.
68- ESC-^B _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>> _<U+0008><_<U+0008>c_<U+0008>2_<U+0008>> * Find open bracket _<U+0008><_<U+0008>c_<U+0008>1_<U+0008>>.
69- ---------------------------------------------------
70- Each "find close bracket" command goes forward to the close bracket
71- matching the (_<U+0008>N-th) open bracket in the top line.
72- Each "find open bracket" command goes backward to the open bracket
73- matching the (_<U+0008>N-th) close bracket in the bottom line.
74-
75- m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current top line with <letter>.
76- M_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Mark the current bottom line with <letter>.
77- '_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Go to a previously marked position.
78- '' Go to the previous position.
79- ^X^X Same as '.
80- ESC-m_<U+0008><_<U+0008>l_<U+0008>e_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>> Clear a mark.
81- ---------------------------------------------------
82- A mark is any upper-case or lower-case letter.
83- Certain marks are predefined:
84- ^ means beginning of the file
85- $ means end of the file
86- ---------------------------------------------------------------------------
87-
88- C<U+0008>CH<U+0008>HA<U+0008>AN<U+0008>NG<U+0008>GI<U+0008>IN<U+0008>NG<U+0008>G F<U+0008>FI<U+0008>IL<U+0008>LE<U+0008>ES<U+0008>S
89-
90- :e [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] Examine a new file.
91- ^X^V Same as :e.
92- :n * Examine the (_<U+0008>N-th) next file from the command line.
93- :p * Examine the (_<U+0008>N-th) previous file from the command line.
94- :x * Examine the first (or _<U+0008>N-th) file from the command line.
95- :d Delete the current file from the command line list.
96- = ^G :f Print current file name.
97- ---------------------------------------------------------------------------
98-
99- M<U+0008>MI<U+0008>IS<U+0008>SC<U+0008>CE<U+0008>EL<U+0008>LL<U+0008>LA<U+0008>AN<U+0008>NE<U+0008>EO<U+0008>OU<U+0008>US<U+0008>S C<U+0008>CO<U+0008>OM<U+0008>MM<U+0008>MA<U+0008>AN<U+0008>ND<U+0008>DS<U+0008>S
100-
101- -_<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Toggle a command line option [see OPTIONS below].
102- --_<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Toggle a command line option, by name.
103- __<U+0008><_<U+0008>f_<U+0008>l_<U+0008>a_<U+0008>g_<U+0008>> Display the setting of a command line option.
104- ___<U+0008><_<U+0008>n_<U+0008>a_<U+0008>m_<U+0008>e_<U+0008>> Display the setting of an option, by name.
105- +_<U+0008>c_<U+0008>m_<U+0008>d Execute the less cmd each time a new file is examined.
106-
107- !_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command with $SHELL.
108- #_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Execute the shell command, expanded like a prompt.
109- |X<U+0008>X_<U+0008>c_<U+0008>o_<U+0008>m_<U+0008>m_<U+0008>a_<U+0008>n_<U+0008>d Pipe file between current pos & mark X<U+0008>X to shell command.
110- s _<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e Save input to a file.
111- v Edit the current file with $VISUAL or $EDITOR.
112- V Print version number of "less".
113- ---------------------------------------------------------------------------
114-
115- O<U+0008>OP<U+0008>PT<U+0008>TI<U+0008>IO<U+0008>ON<U+0008>NS<U+0008>S
116-
117- Most options may be changed either on the command line,
118- or from within less by using the - or -- command.
119- Options may be given in one of two forms: either a single
120- character preceded by a -, or a name preceded by --.
121-
122- -? ........ --help
123- Display help (from command line).
124- -a ........ --search-skip-screen
125- Search skips current screen.
126- -A ........ --SEARCH-SKIP-SCREEN
127- Search starts just after target line.
128- -b [_<U+0008>N] .... --buffers=[_<U+0008>N]
129- Number of buffers.
130- -B ........ --auto-buffers
131- Don't automatically allocate buffers for pipes.
132- -c ........ --clear-screen
133- Repaint by clearing rather than scrolling.
134- -d ........ --dumb
135- Dumb terminal.
136- -D x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r . --color=x<U+0008>x_<U+0008>c_<U+0008>o_<U+0008>l_<U+0008>o_<U+0008>r
137- Set screen colors.
138- -e -E .... --quit-at-eof --QUIT-AT-EOF
139- Quit at end of file.
140- -f ........ --force
141- Force open non-regular files.
142- -F ........ --quit-if-one-screen
143- Quit if entire file fits on first screen.
144- -g ........ --hilite-search
145- Highlight only last match for searches.
146- -G ........ --HILITE-SEARCH
147- Don't highlight any matches for searches.
148- -h [_<U+0008>N] .... --max-back-scroll=[_<U+0008>N]
149- Backward scroll limit.
150- -i ........ --ignore-case
151- Ignore case in searches that do not contain uppercase.
152- -I ........ --IGNORE-CASE
153- Ignore case in all searches.
154- -j [_<U+0008>N] .... --jump-target=[_<U+0008>N]
155- Screen position of target lines.
156- -J ........ --status-column
157- Display a status column at left edge of screen.
158- -k [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --lesskey-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
159- Use a lesskey file.
160- -K ........ --quit-on-intr
161- Exit less in response to ctrl-C.
162- -L ........ --no-lessopen
163- Ignore the LESSOPEN environment variable.
164- -m -M .... --long-prompt --LONG-PROMPT
165- Set prompt style.
166- -n ......... --line-numbers
167- Suppress line numbers in prompts and messages.
168- -N ......... --LINE-NUMBERS
169- Display line number at start of each line.
170- -o [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --log-file=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
171- Copy to log file (standard input only).
172- -O [_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] . --LOG-FILE=[_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
173- Copy to log file (unconditionally overwrite).
174- -p [_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n] --pattern=[_<U+0008>p_<U+0008>a_<U+0008>t_<U+0008>t_<U+0008>e_<U+0008>r_<U+0008>n]
175- Start at pattern (from command line).
176- -P [_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t] --prompt=[_<U+0008>p_<U+0008>r_<U+0008>o_<U+0008>m_<U+0008>p_<U+0008>t]
177- Define new prompt.
178- -q -Q .... --quiet --QUIET --silent --SILENT
179- Quiet the terminal bell.
180- -r -R .... --raw-control-chars --RAW-CONTROL-CHARS
181- Output "raw" control characters.
182- -s ........ --squeeze-blank-lines
183- Squeeze multiple blank lines.
184- -S ........ --chop-long-lines
185- Chop (truncate) long lines rather than wrapping.
186- -t [_<U+0008>t_<U+0008>a_<U+0008>g] .. --tag=[_<U+0008>t_<U+0008>a_<U+0008>g]
187- Find a tag.
188- -T [_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e] --tag-file=[_<U+0008>t_<U+0008>a_<U+0008>g_<U+0008>s_<U+0008>f_<U+0008>i_<U+0008>l_<U+0008>e]
189- Use an alternate tags file.
190- -u -U .... --underline-special --UNDERLINE-SPECIAL
191- Change handling of backspaces, tabs and carriage returns.
192- -V ........ --version
193- Display the version number of "less".
194- -w ........ --hilite-unread
195- Highlight first new line after forward-screen.
196- -W ........ --HILITE-UNREAD
197- Highlight first new line after any forward movement.
198- -x [_<U+0008>N[,...]] --tabs=[_<U+0008>N[,...]]
199- Set tab stops.
200- -X ........ --no-init
201- Don't use termcap init/deinit strings.
202- -y [_<U+0008>N] .... --max-forw-scroll=[_<U+0008>N]
203- Forward scroll limit.
204- -z [_<U+0008>N] .... --window=[_<U+0008>N]
205- Set size of window.
206- -" [_<U+0008>c[_<U+0008>c]] . --quotes=[_<U+0008>c[_<U+0008>c]]
207- Set shell quote characters.
208- -~ ........ --tilde
209- Don't display tildes after end of file.
210- -# [_<U+0008>N] .... --shift=[_<U+0008>N]
211- Set horizontal scroll amount (0 = one half screen width).
212- --exit-follow-on-close
213- Exit F command on a pipe when writer closes pipe.
214- --file-size
215- Automatically determine the size of the input file.
216- --follow-name
217- The F command changes files if the input file is renamed.
218- --header=[_<U+0008>N[,_<U+0008>M]]
219- Use N lines and M columns to display file headers.
220- --incsearch
221- Search file as each pattern character is typed in.
222- --intr=_<U+0008>C
223- Use _<U+0008>C instead of ^X to interrupt a read.
224- --line-num-width=_<U+0008>N
225- Set the width of the -N line number field to _<U+0008>N characters.
226- --modelines=_<U+0008>N
227- Read _<U+0008>N lines from the input file and look for vim modelines.
228- --mouse
229- Enable mouse input.
230- --no-keypad
231- Don't send termcap keypad init/deinit strings.
232- --no-histdups
233- Remove duplicates from command history.
234- --no-number-headers
235- Don't give line numbers to header lines.
236- --no-search-headers
237- Don't search in header lines or columns.
238- --no-vbell
239- Disable the terminal's visual bell.
240- --redraw-on-quit
241- Redraw final screen when quitting.
242- --rscroll=_<U+0008>C
243- Set the character used to mark truncated lines.
244- --save-marks
245- Retain marks across invocations of less.
246- --search-options=[EFKNRW-]
247- Set default options for every search.
248- --show-preproc-errors
249- Display a message if preprocessor exits with an error status.
250- --proc-backspace
251- Process backspaces for bold/underline.
252- --SPECIAL-BACKSPACE
253- Treat backspaces as control characters.
254- --proc-return
255- Delete carriage returns before newline.
256- --SPECIAL-RETURN
257- Treat carriage returns as control characters.
258- --proc-tab
259- Expand tabs to spaces.
260- --SPECIAL-TAB
261- Treat tabs as control characters.
262- --status-col-width=_<U+0008>N
263- Set the width of the -J status column to _<U+0008>N characters.
264- --status-line
265- Highlight or color the entire line containing a mark.
266- --use-backslash
267- Subsequent options use backslash as escape char.
268- --use-color
269- Enables colored text.
270- --wheel-lines=_<U+0008>N
271- Each click of the mouse wheel moves _<U+0008>N lines.
272- --wordwrap
273- Wrap lines at spaces.
274-
275-
276- ---------------------------------------------------------------------------
277-
278- L<U+0008>LI<U+0008>IN<U+0008>NE<U+0008>E E<U+0008>ED<U+0008>DI<U+0008>IT<U+0008>TI<U+0008>IN<U+0008>NG<U+0008>G
279-
280- These keys can be used to edit text being entered
281- on the "command line" at the bottom of the screen.
282-
283- RightArrow ..................... ESC-l ... Move cursor right one character.
284- LeftArrow ...................... ESC-h ... Move cursor left one character.
285- ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
286- ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
287- HOME ........................... ESC-0 ... Move cursor to start of line.
288- END ............................ ESC-$ ... Move cursor to end of line.
289- BACKSPACE ................................ Delete char to left of cursor.
290- DELETE ......................... ESC-x ... Delete char under cursor.
291- ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
292- ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
293- ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
294- UpArrow ........................ ESC-k ... Retrieve previous command line.
295- DownArrow ...................... ESC-j ... Retrieve next command line.
296- TAB ...................................... Complete filename & cycle.
297- SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
298- ctrl-L ................................... Complete filename, list all.
D tall-traefik-form" +0 -404
@@ -1,404 +0,0 @@
1-<U+001B>[1mdiff --git a/changes.txt b/changes.txt<U+001B>[m
2-<U+001B>[1mdeleted file mode 100644<U+001B>[m
3-<U+001B>[1mindex ab78b90..0000000<U+001B>[m
4-<U+001B>[1m--- a/changes.txt<U+001B>[m
5-<U+001B>[1m+++ /dev/null<U+001B>[m
6-<U+001B>[36m@@ -1,326 +0,0 @@<U+001B>[m
7-<U+001B>[31m-diff --git a/:memory b/:memory<U+001B>[m
8-<U+001B>[31m-new file mode 100644<U+001B>[m
9-<U+001B>[31m-index 0000000..9760229<U+001B>[m
10-<U+001B>[31m-Binary files /dev/null and b/:memory differ<U+001B>[m
11-<U+001B>[31m-diff --git a/cmd/main.go b/cmd/main.go<U+001B>[m
12-<U+001B>[31m-index 6a95d32..b8e2cd4 100644<U+001B>[m
13-<U+001B>[31m---- a/cmd/main.go<U+001B>[m
14-<U+001B>[31m-+++ b/cmd/main.go<U+001B>[m
15-<U+001B>[31m-@@ -4,17 +4,30 @@ import (<U+001B>[m
16-<U+001B>[31m- "fmt"<U+001B>[m
17-<U+001B>[31m- "log/slog"<U+001B>[m
18-<U+001B>[31m- <U+001B>[m
19-<U+001B>[31m-+ "github.com/labstack/echo/v4"<U+001B>[m
20-<U+001B>[31m-+<U+001B>[m
21-<U+001B>[31m- "github.com/bnema/gordon/internal/app"<U+001B>[m
22-<U+001B>[31m- "github.com/bnema/gordon/internal/httpserve"<U+001B>[m
23-<U+001B>[31m-- "github.com/labstack/echo/v4"<U+001B>[m
24-<U+001B>[31m- )<U+001B>[m
25-<U+001B>[31m- <U+001B>[m
26-<U+001B>[31m- func main() {<U+001B>[m
27-<U+001B>[31m- a := app.NewApp()<U+001B>[m
28-<U+001B>[31m-+<U+001B>[m
29-<U+001B>[31m-+ // Initialize database<U+001B>[m
30-<U+001B>[31m-+ db, err := app.InitializeDB(a)<U+001B>[m
31-<U+001B>[31m-+ if err != nil {<U+001B>[m
32-<U+001B>[31m-+ slog.Error("Failed to load database", err)<U+001B>[m
33-<U+001B>[31m-+ } else {<U+001B>[m
34-<U+001B>[31m-+ slog.Info("Database loaded")<U+001B>[m
35-<U+001B>[31m-+ }<U+001B>[m
36-<U+001B>[31m-+<U+001B>[m
37-<U+001B>[31m-+ fmt.Println(db)<U+001B>[m
38-<U+001B>[31m-+<U+001B>[m
39-<U+001B>[31m- e := echo.New()<U+001B>[m
40-<U+001B>[31m- e.HideBanner = true<U+001B>[m
41-<U+001B>[31m- e.HidePort = true<U+001B>[m
42-<U+001B>[31m- e = httpserve.RegisterRoutes(e, a)<U+001B>[m
43-<U+001B>[31m- slog.Info("Starting server", "port", a.HttpPort)<U+001B>[m
44-<U+001B>[31m- slog.Error("Server error", e.Start(fmt.Sprintf(":%d", a.HttpPort)))<U+001B>[m
45-<U+001B>[31m-+<U+001B>[m
46-<U+001B>[31m- }<U+001B>[m
47-<U+001B>[31m-diff --git a/go.mod b/go.mod<U+001B>[m
48-<U+001B>[31m-index 35e2d3c..8a3ac59 100644<U+001B>[m
49-<U+001B>[31m---- a/go.mod<U+001B>[m
50-<U+001B>[31m-+++ b/go.mod<U+001B>[m
51-<U+001B>[31m-@@ -24,6 +24,7 @@ require (<U+001B>[m
52-<U+001B>[31m- github.com/gorilla/securecookie v1.1.1 // indirect<U+001B>[m
53-<U+001B>[31m- github.com/gorilla/sessions v1.2.1 // indirect<U+001B>[m
54-<U+001B>[31m- github.com/klauspost/compress v1.16.7 // indirect<U+001B>[m
55-<U+001B>[31m-+ github.com/kr/text v0.1.0 // indirect<U+001B>[m
56-<U+001B>[31m- github.com/labstack/gommon v0.4.0 // indirect<U+001B>[m
57-<U+001B>[31m- github.com/mattn/go-colorable v0.1.13 // indirect<U+001B>[m
58-<U+001B>[31m- github.com/mattn/go-isatty v0.0.19 // indirect<U+001B>[m
59-<U+001B>[31m-@@ -35,6 +36,7 @@ require (<U+001B>[m
60-<U+001B>[31m- github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect<U+001B>[m
61-<U+001B>[31m- github.com/opencontainers/runc v1.1.9 // indirect<U+001B>[m
62-<U+001B>[31m- github.com/pkg/errors v0.9.1 // indirect<U+001B>[m
63-<U+001B>[31m-+ github.com/rogpeppe/go-internal v1.11.0 // indirect<U+001B>[m
64-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3 // indirect<U+001B>[m
65-<U+001B>[31m- github.com/valyala/bytebufferpool v1.0.0 // indirect<U+001B>[m
66-<U+001B>[31m- github.com/valyala/fasttemplate v1.2.2 // indirect<U+001B>[m
67-<U+001B>[31m-@@ -45,5 +47,6 @@ require (<U+001B>[m
68-<U+001B>[31m- golang.org/x/text v0.11.0 // indirect<U+001B>[m
69-<U+001B>[31m- golang.org/x/time v0.3.0 // indirect<U+001B>[m
70-<U+001B>[31m- golang.org/x/tools v0.7.0 // indirect<U+001B>[m
71-<U+001B>[31m-+ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect<U+001B>[m
72-<U+001B>[31m- gotest.tools/v3 v3.5.0 // indirect<U+001B>[m
73-<U+001B>[31m- )<U+001B>[m
74-<U+001B>[31m-diff --git a/go.sum b/go.sum<U+001B>[m
75-<U+001B>[31m-index 7b9b857..17b0bcd 100644<U+001B>[m
76-<U+001B>[31m---- a/go.sum<U+001B>[m
77-<U+001B>[31m-+++ b/go.sum<U+001B>[m
78-<U+001B>[31m-@@ -39,6 +39,11 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI<U+001B>[m
79-<U+001B>[31m- github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=<U+001B>[m
80-<U+001B>[31m- github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=<U+001B>[m
81-<U+001B>[31m- github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=<U+001B>[m
82-<U+001B>[31m-+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=<U+001B>[m
83-<U+001B>[31m-+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=<U+001B>[m
84-<U+001B>[31m-+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=<U+001B>[m
85-<U+001B>[31m-+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=<U+001B>[m
86-<U+001B>[31m-+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=<U+001B>[m
87-<U+001B>[31m- github.com/labstack/echo-contrib v0.15.0 h1:9K+oRU265y4Mu9zpRDv3X+DGTqUALY6oRHCSZZKCRVU=<U+001B>[m
88-<U+001B>[31m- github.com/labstack/echo-contrib v0.15.0/go.mod h1:lei+qt5CLB4oa7VHTE0yEfQSEB9XTJI1LUqko9UWvo4=<U+001B>[m
89-<U+001B>[31m- github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4=<U+001B>[m
90-<U+001B>[31m-@@ -72,6 +77,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=<U+001B>[m
91-<U+001B>[31m- github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=<U+001B>[m
92-<U+001B>[31m- github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=<U+001B>[m
93-<U+001B>[31m- github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=<U+001B>[m
94-<U+001B>[31m-+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=<U+001B>[m
95-<U+001B>[31m-+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=<U+001B>[m
96-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=<U+001B>[m
97-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=<U+001B>[m
98-<U+001B>[31m- github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=<U+001B>[m
99-<U+001B>[31m-@@ -153,8 +160,9 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T<U+001B>[m
100-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
101-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
102-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
103-<U+001B>[31m--gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=<U+001B>[m
104-<U+001B>[31m- gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=<U+001B>[m
105-<U+001B>[31m-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=<U+001B>[m
106-<U+001B>[31m-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=<U+001B>[m
107-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=<U+001B>[m
108-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=<U+001B>[m
109-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=<U+001B>[m
110-<U+001B>[31m-diff --git a/internal/app/app.go b/internal/app/app.go<U+001B>[m
111-<U+001B>[31m-index c6f49ac..1dd44b8 100644<U+001B>[m
112-<U+001B>[31m---- a/internal/app/app.go<U+001B>[m
113-<U+001B>[31m-+++ b/internal/app/app.go<U+001B>[m
114-<U+001B>[31m-@@ -27,6 +27,7 @@ const (<U+001B>[m
115-<U+001B>[31m- type App struct {<U+001B>[m
116-<U+001B>[31m- TemplateFS fs.FS<U+001B>[m
117-<U+001B>[31m- PublicFS fs.FS<U+001B>[m
118-<U+001B>[31m-+ DB interface{}<U+001B>[m
119-<U+001B>[31m- BuildVersion string<U+001B>[m
120-<U+001B>[31m- BuildDir string<U+001B>[m
121-<U+001B>[31m- DBDir string<U+001B>[m
122-<U+001B>[31m-diff --git a/internal/app/sqlite.go b/internal/app/sqlite.go<U+001B>[m
123-<U+001B>[31m-index 9f1b1ab..ddc6a1e 100644<U+001B>[m
124-<U+001B>[31m---- a/internal/app/sqlite.go<U+001B>[m
125-<U+001B>[31m-+++ b/internal/app/sqlite.go<U+001B>[m
126-<U+001B>[31m-@@ -5,58 +5,78 @@ import (<U+001B>[m
127-<U+001B>[31m- "database/sql"<U+001B>[m
128-<U+001B>[31m- "fmt"<U+001B>[m
129-<U+001B>[31m- "os"<U+001B>[m
130-<U+001B>[31m-+ "path/filepath"<U+001B>[m
131-<U+001B>[31m- <U+001B>[m
132-<U+001B>[31m-- sqlite3 "github.com/mattn/go-sqlite3"<U+001B>[m
133-<U+001B>[31m-+ "github.com/bnema/gordon/internal/database/migrate"<U+001B>[m
134-<U+001B>[31m-+ "github.com/mattn/go-sqlite3"<U+001B>[m
135-<U+001B>[31m- )<U+001B>[m
136-<U+001B>[31m- <U+001B>[m
137-<U+001B>[31m--// Initialize in-memory SQLite database and returns its connection<U+001B>[m
138-<U+001B>[31m--func InitDB() (db *sql.DB, err error) {<U+001B>[m
139-<U+001B>[31m-- db, err = sql.Open("sqlite3", "file::memory?cache=shared")<U+001B>[m
140-<U+001B>[31m-- if err != nil {<U+001B>[m
141-<U+001B>[31m-- return nil, fmt.Errorf("failed to open in-memory database: %v", err)<U+001B>[m
142-<U+001B>[31m-- }<U+001B>[m
143-<U+001B>[31m-- return<U+001B>[m
144-<U+001B>[31m--}<U+001B>[m
145-<U+001B>[31m--<U+001B>[m
146-<U+001B>[31m--// CloseDB closes the database connection and backs up the in-memory database to disk<U+001B>[m
147-<U+001B>[31m--func CloseDB(db *sql.DB, a *App) error {<U+001B>[m
148-<U+001B>[31m-- if err := BackupDB(db, a); err != nil {<U+001B>[m
149-<U+001B>[31m-- return err<U+001B>[m
150-<U+001B>[31m-- }<U+001B>[m
151-<U+001B>[31m-+// InitializeDB initializes the SQLite database. If a database file exists on disk, it loads it into memory.<U+001B>[m
152-<U+001B>[31m-+// Otherwise, it creates a new in-memory database and bootstraps it.<U+001B>[m
153-<U+001B>[31m-+func InitializeDB(a *App) (*sql.DB, error) {<U+001B>[m
154-<U+001B>[31m-+ dbfp := a.GetDBFilePath()<U+001B>[m
155-<U+001B>[31m- <U+001B>[m
156-<U+001B>[31m-- if err := db.Close(); err != nil {<U+001B>[m
157-<U+001B>[31m-- return fmt.Errorf("failed to close database: %v", err)<U+001B>[m
158-<U+001B>[31m-+ // Check if the directory exists, if not create it<U+001B>[m
159-<U+001B>[31m-+ dir := filepath.Dir(a.DBDir)<U+001B>[m
160-<U+001B>[31m-+ fmt.Println("dir", dir)<U+001B>[m
161-<U+001B>[31m-+ if _, err := os.Stat(dir); os.IsNotExist(err) {<U+001B>[m
162-<U+001B>[31m-+ err = os.MkdirAll(dir, 0755)<U+001B>[m
163-<U+001B>[31m-+ if err != nil {<U+001B>[m
164-<U+001B>[31m-+ return nil, fmt.Errorf("failed to create directory: %v", err)<U+001B>[m
165-<U+001B>[31m-+ }<U+001B>[m
166-<U+001B>[31m- }<U+001B>[m
167-<U+001B>[31m- <U+001B>[m
168-<U+001B>[31m-- return nil<U+001B>[m
169-<U+001B>[31m--}<U+001B>[m
170-<U+001B>[31m-+ // If the database file doesn't exist on disk<U+001B>[m
171-<U+001B>[31m-+ if _, err := os.Stat(dbfp); os.IsNotExist(err) {<U+001B>[m
172-<U+001B>[31m-+ memDB, err := initInMemoryDB()<U+001B>[m
173-<U+001B>[31m-+ if err != nil {<U+001B>[m
174-<U+001B>[31m-+ return nil, err<U+001B>[m
175-<U+001B>[31m-+ }<U+001B>[m
176-<U+001B>[31m- <U+001B>[m
177-<U+001B>[31m--// LoadDBIntoMemory loads the database from disk into memory<U+001B>[m
178-<U+001B>[31m--func LoadDBIntoMemory(a *App) (*sql.DB, error) {<U+001B>[m
179-<U+001B>[31m-- dbfp := a.GetDBFilePath()<U+001B>[m
180-<U+001B>[31m-+ // Run the bootstrap<U+001B>[m
181-<U+001B>[31m-+ RunBootstrap(memDB)<U+001B>[m
182-<U+001B>[31m- <U+001B>[m
183-<U+001B>[31m-- if _, err := os.Stat(dbfp); err != nil {<U+001B>[m
184-<U+001B>[31m-- return nil, nil<U+001B>[m
185-<U+001B>[31m-+ // Explicitly backup the in-memory database to disk<U+001B>[m
186-<U+001B>[31m-+ err = BackupDB(memDB, a)<U+001B>[m
187-<U+001B>[31m-+ if err != nil {<U+001B>[m
188-<U+001B>[31m-+ return nil, fmt.Errorf("failed to backup in-memory database to disk: %v", err)<U+001B>[m
189-<U+001B>[31m-+ }<U+001B>[m
190-<U+001B>[31m- }<U+001B>[m
191-<U+001B>[31m- <U+001B>[m
192-<U+001B>[31m-- memDB, err := InitDB()<U+001B>[m
193-<U+001B>[31m-+ memDB, err := initInMemoryDB()<U+001B>[m
194-<U+001B>[31m- if err != nil {<U+001B>[m
195-<U+001B>[31m- return nil, err<U+001B>[m
196-<U+001B>[31m- }<U+001B>[m
197-<U+001B>[31m--<U+001B>[m
198-<U+001B>[31m- diskDB, err := sql.Open("sqlite3", dbfp)<U+001B>[m
199-<U+001B>[31m- if err != nil {<U+001B>[m
200-<U+001B>[31m- return nil, fmt.Errorf("failed to open database file: %v", err)<U+001B>[m
201-<U+001B>[31m- }<U+001B>[m
202-<U+001B>[31m-+ defer diskDB.Close()<U+001B>[m
203-<U+001B>[31m- <U+001B>[m
204-<U+001B>[31m- if err := transferData(diskDB, memDB); err != nil {<U+001B>[m
205-<U+001B>[31m- return nil, err<U+001B>[m
206-<U+001B>[31m- }<U+001B>[m
207-<U+001B>[31m--<U+001B>[m
208-<U+001B>[31m- return memDB, nil<U+001B>[m
209-<U+001B>[31m- }<U+001B>[m
210-<U+001B>[31m- <U+001B>[m
211-<U+001B>[31m--// transferData transfers data from srcDB to dstDB<U+001B>[m
212-<U+001B>[31m-+func initInMemoryDB() (*sql.DB, error) {<U+001B>[m
213-<U+001B>[31m-+ db, err := sql.Open("sqlite3", "file::memory?cache=shared")<U+001B>[m
214-<U+001B>[31m-+ if err != nil {<U+001B>[m
215-<U+001B>[31m-+ return nil, fmt.Errorf("failed to open in-memory database: %v", err)<U+001B>[m
216-<U+001B>[31m-+ }<U+001B>[m
217-<U+001B>[31m-+ return db, nil<U+001B>[m
218-<U+001B>[31m-+}<U+001B>[m
219-<U+001B>[31m-+<U+001B>[m
220-<U+001B>[31m-+func CloseAndBackupDB(db *sql.DB, a *App) error {<U+001B>[m
221-<U+001B>[31m-+ if err := BackupDB(db, a); err != nil {<U+001B>[m
222-<U+001B>[31m-+ return err<U+001B>[m
223-<U+001B>[31m-+ }<U+001B>[m
224-<U+001B>[31m-+ if err := db.Close(); err != nil {<U+001B>[m
225-<U+001B>[31m-+ return fmt.Errorf("failed to close database: %v", err)<U+001B>[m
226-<U+001B>[31m-+ }<U+001B>[m
227-<U+001B>[31m-+ return nil<U+001B>[m
228-<U+001B>[31m-+}<U+001B>[m
229-<U+001B>[31m-+<U+001B>[m
230-<U+001B>[31m- func transferData(srcDB, dstDB *sql.DB) error {<U+001B>[m
231-<U+001B>[31m- srcConn, err := srcDB.Conn(context.Background())<U+001B>[m
232-<U+001B>[31m- if err != nil {<U+001B>[m
233-<U+001B>[31m-@@ -74,35 +94,50 @@ func transferData(srcDB, dstDB *sql.DB) error {<U+001B>[m
234-<U+001B>[31m- return dstConn.Raw(func(dstRawConn interface{}) error {<U+001B>[m
235-<U+001B>[31m- srcSqlite3Conn := srcRawConn.(*sqlite3.SQLiteConn)<U+001B>[m
236-<U+001B>[31m- dstSqlite3Conn := dstRawConn.(*sqlite3.SQLiteConn)<U+001B>[m
237-<U+001B>[31m--<U+001B>[m
238-<U+001B>[31m- _, err := srcSqlite3Conn.Backup("main", dstSqlite3Conn, "main")<U+001B>[m
239-<U+001B>[31m- return err<U+001B>[m
240-<U+001B>[31m- })<U+001B>[m
241-<U+001B>[31m- })<U+001B>[m
242-<U+001B>[31m- }<U+001B>[m
243-<U+001B>[31m- <U+001B>[m
244-<U+001B>[31m--// BackupDB backs up the in-memory database to disk<U+001B>[m
245-<U+001B>[31m- func BackupDB(db *sql.DB, a *App) error {<U+001B>[m
246-<U+001B>[31m- dbfp := a.GetDBFilePath()<U+001B>[m
247-<U+001B>[31m--<U+001B>[m
248-<U+001B>[31m- conn, err := db.Conn(context.Background())<U+001B>[m
249-<U+001B>[31m- if err != nil {<U+001B>[m
250-<U+001B>[31m- return fmt.Errorf("failed to get underlying database connection: %v", err)<U+001B>[m
251-<U+001B>[31m- }<U+001B>[m
252-<U+001B>[31m-+ defer conn.Close()<U+001B>[m
253-<U+001B>[31m- <U+001B>[m
254-<U+001B>[31m- return conn.Raw(func(sqliteConn interface{}) error {<U+001B>[m
255-<U+001B>[31m- sqlite3Conn := sqliteConn.(*sqlite3.SQLiteConn)<U+001B>[m
256-<U+001B>[31m-- backupDB, err := sqlite3Conn.Backup(dbfp, sqlite3Conn, "main")<U+001B>[m
257-<U+001B>[31m-+ diskDB, err := sql.Open("sqlite3", dbfp)<U+001B>[m
258-<U+001B>[31m-+ fmt.Println("diskDB", diskDB)<U+001B>[m
259-<U+001B>[31m-+ if err != nil {<U+001B>[m
260-<U+001B>[31m-+ return fmt.Errorf("failed to open destination database file: %v", err)<U+001B>[m
261-<U+001B>[31m-+ }<U+001B>[m
262-<U+001B>[31m-+ defer diskDB.Close()<U+001B>[m
263-<U+001B>[31m-+<U+001B>[m
264-<U+001B>[31m-+ diskConn, err := diskDB.Conn(context.Background())<U+001B>[m
265-<U+001B>[31m- if err != nil {<U+001B>[m
266-<U+001B>[31m-- return fmt.Errorf("failed to create backup: %v", err)<U+001B>[m
267-<U+001B>[31m-+ return fmt.Errorf("failed to get connection from diskDB: %v", err)<U+001B>[m
268-<U+001B>[31m- }<U+001B>[m
269-<U+001B>[31m-+ defer diskConn.Close()<U+001B>[m
270-<U+001B>[31m-+<U+001B>[m
271-<U+001B>[31m-+ var backupDB *sqlite3.SQLiteBackup<U+001B>[m
272-<U+001B>[31m-+ err = diskConn.Raw(func(diskRawConn interface{}) error {<U+001B>[m
273-<U+001B>[31m-+ backupDB, err = sqlite3Conn.Backup("main", diskRawConn.(*sqlite3.SQLiteConn), "main")<U+001B>[m
274-<U+001B>[31m-+ return err<U+001B>[m
275-<U+001B>[31m-+ })<U+001B>[m
276-<U+001B>[31m- defer backupDB.Close()<U+001B>[m
277-<U+001B>[31m- <U+001B>[m
278-<U+001B>[31m- _, err = backupDB.Step(-1)<U+001B>[m
279-<U+001B>[31m- if err != nil {<U+001B>[m
280-<U+001B>[31m- return fmt.Errorf("failed to backup in-memory database: %v", err)<U+001B>[m
281-<U+001B>[31m- }<U+001B>[m
282-<U+001B>[31m--<U+001B>[m
283-<U+001B>[31m- return nil<U+001B>[m
284-<U+001B>[31m- })<U+001B>[m
285-<U+001B>[31m- }<U+001B>[m
286-<U+001B>[31m-+<U+001B>[m
287-<U+001B>[31m-+func RunBootstrap(db *sql.DB) error {<U+001B>[m
288-<U+001B>[31m-+ return migrate.CreateUserTable(db)<U+001B>[m
289-<U+001B>[31m-+}<U+001B>[m
290-<U+001B>[31m-diff --git a/internal/database/migrate/bootstrapdb.go b/internal/database/migrate/bootstrapdb.go<U+001B>[m
291-<U+001B>[31m-new file mode 100644<U+001B>[m
292-<U+001B>[31m-index 0000000..1f53246<U+001B>[m
293-<U+001B>[31m---- /dev/null<U+001B>[m
294-<U+001B>[31m-+++ b/internal/database/migrate/bootstrapdb.go<U+001B>[m
295-<U+001B>[31m-@@ -0,0 +1,24 @@<U+001B>[m
296-<U+001B>[31m-+package migrate<U+001B>[m
297-<U+001B>[31m-+<U+001B>[m
298-<U+001B>[31m-+import (<U+001B>[m
299-<U+001B>[31m-+ "database/sql"<U+001B>[m
300-<U+001B>[31m-+ "fmt"<U+001B>[m
301-<U+001B>[31m-+)<U+001B>[m
302-<U+001B>[31m-+<U+001B>[m
303-<U+001B>[31m-+// createUserTable creates the 'user' table in the provided SQLite database.<U+001B>[m
304-<U+001B>[31m-+func CreateUserTable(db *sql.DB) error {<U+001B>[m
305-<U+001B>[31m-+ createTableSQL := `<U+001B>[m
306-<U+001B>[31m-+ CREATE TABLE user (<U+001B>[m
307-<U+001B>[31m-+ id INTEGER PRIMARY KEY AUTOINCREMENT,<U+001B>[m
308-<U+001B>[31m-+ username TEXT NOT NULL,<U+001B>[m
309-<U+001B>[31m-+ password TEXT NOT NULL, -- This should be hashed and salted in a real-world scenario.<U+001B>[m
310-<U+001B>[31m-+ oauth_token TEXT<U+001B>[m
311-<U+001B>[31m-+ );`<U+001B>[m
312-<U+001B>[31m-+<U+001B>[m
313-<U+001B>[31m-+ _, err := db.Exec(createTableSQL)<U+001B>[m
314-<U+001B>[31m-+ if err != nil {<U+001B>[m
315-<U+001B>[31m-+ return fmt.Errorf("failed to create user table: %v", err)<U+001B>[m
316-<U+001B>[31m-+ }<U+001B>[m
317-<U+001B>[31m-+<U+001B>[m
318-<U+001B>[31m-+ return nil<U+001B>[m
319-<U+001B>[31m-+}<U+001B>[m
320-<U+001B>[31m-diff --git a/internal/httpserve/handler/adminroutes.go b/internal/httpserve/handler/adminroutes.go<U+001B>[m
321-<U+001B>[31m-index 8701ae3..f4acd64 100644<U+001B>[m
322-<U+001B>[31m---- a/internal/httpserve/handler/adminroutes.go<U+001B>[m
323-<U+001B>[31m-+++ b/internal/httpserve/handler/adminroutes.go<U+001B>[m
324-<U+001B>[31m-@@ -1,8 +1,6 @@<U+001B>[m
325-<U+001B>[31m- package handler<U+001B>[m
326-<U+001B>[31m- <U+001B>[m
327-<U+001B>[31m- import (<U+001B>[m
328-<U+001B>[31m-- "fmt"<U+001B>[m
329-<U+001B>[31m--<U+001B>[m
330-<U+001B>[31m- "github.com/bnema/gordon/internal/app"<U+001B>[m
331-<U+001B>[31m- "github.com/bnema/gordon/internal/gotemplate/render"<U+001B>[m
332-<U+001B>[31m- "github.com/bnema/gordon/internal/httpserve/middleware"<U+001B>[m
333-<U+001B>[1mdiff --git a/internal/httpserve/handler/oauth.go b/internal/httpserve/handler/oauth.go<U+001B>[m
334-<U+001B>[1mindex bd40379..b876c75 100644<U+001B>[m
335-<U+001B>[1m--- a/internal/httpserve/handler/oauth.go<U+001B>[m
336-<U+001B>[1m+++ b/internal/httpserve/handler/oauth.go<U+001B>[m
337-<U+001B>[36m@@ -12,6 +12,7 @@<U+001B>[m <U+001B>[mimport (<U+001B>[m
338- "github.com/markbates/goth/gothic"<U+001B>[m
339- "github.com/markbates/goth/providers/github"<U+001B>[m
340- "net/http"<U+001B>[m
341-<U+001B>[32m+<U+001B>[m <U+001B>[32m"os"<U+001B>[m
342- )<U+001B>[m
343- <U+001B>[m
344- var providerNames []string<U+001B>[m
345-<U+001B>[1mdiff --git a/internal/httpserve/router.go b/internal/httpserve/router.go<U+001B>[m
346-<U+001B>[1mindex bc1368c..edd2748 100644<U+001B>[m
347-<U+001B>[1m--- a/internal/httpserve/router.go<U+001B>[m
348-<U+001B>[1m+++ b/internal/httpserve/router.go<U+001B>[m
349-<U+001B>[36m@@ -19,34 +19,19 @@<U+001B>[m <U+001B>[mfunc RegisterRoutes(e *echo.Echo, a *app.App) *echo.Echo {<U+001B>[m
350- // Use session middleware<U+001B>[m
351- // Add session middleware<U+001B>[m
352- e.Use(session.Middleware(sessions.NewCookieStore([]byte(os.Getenv("SECRET")))))<U+001B>[m
353-<U+001B>[31m- // e.Use(middleware.SecureRoutes())<U+001B>[m
354- e.Use(middleware.ColorSchemeDetection)<U+001B>[m
355- e.Use(middleware.LanguageDetection)<U+001B>[m
356- <U+001B>[m
357- // Register routes<U+001B>[m
358-<U+001B>[31m-<U+001B>[m
359-<U+001B>[31m- // Serve admin routes<U+001B>[m
360- bindAdminRoute(e, a, AdminPath)<U+001B>[m
361-<U+001B>[31m- // Serve static files<U+001B>[m
362- bindStaticRoute(e, a, "/*")<U+001B>[m
363-<U+001B>[32m+<U+001B>[m <U+001B>[32mbindLoginRoute(e, a, AdminPath)<U+001B>[m
364-<U+001B>[32m+<U+001B>[m
365- // Protect the root path with a 403<U+001B>[m
366- e.GET("/", func(c echo.Context) error {<U+001B>[m
367- return c.String(403, "403 Forbidden")<U+001B>[m
368- })<U+001B>[m
369- <U+001B>[m
370-<U+001B>[31m- e.GET(a.AdminPath+"/login", func(c echo.Context) error {<U+001B>[m
371-<U+001B>[31m- return handler.RenderLoginPage(c, a)<U+001B>[m
372-<U+001B>[31m- })<U+001B>[m
373-<U+001B>[31m- e.GET(a.AdminPath+"/login/:provider", func(c echo.Context) error {<U+001B>[m
374-<U+001B>[31m- return handler.StartOAuth(c, a)<U+001B>[m
375-<U+001B>[31m- })<U+001B>[m
376-<U+001B>[31m- e.GET(a.OauthCallbackURL, func(c echo.Context) error {<U+001B>[m
377-<U+001B>[31m- return handler.OAuthCallback(c, a)<U+001B>[m
378-<U+001B>[31m- })<U+001B>[m
379-<U+001B>[31m- e.GET(a.AdminPath+"/logout", func(c echo.Context) error {<U+001B>[m
380-<U+001B>[31m- return handler.Logout(c, a)<U+001B>[m
381-<U+001B>[31m- })<U+001B>[m
382-<U+001B>[31m-<U+001B>[m
383- return e<U+001B>[m
384- }<U+001B>[m
385- <U+001B>[m
386-<U+001B>[36m@@ -61,3 +46,18 @@<U+001B>[m <U+001B>[mfunc bindAdminRoute(e *echo.Echo, a *app.App, path string) {<U+001B>[m
387- return handler.AdminRoute(c, a)<U+001B>[m
388- })<U+001B>[m
389- }<U+001B>[m
390-<U+001B>[32m+<U+001B>[m
391-<U+001B>[32m+<U+001B>[m<U+001B>[32mfunc bindLoginRoute(e *echo.Echo, a *app.App, adminPath string) {<U+001B>[m
392-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/login", func(c echo.Context) error {<U+001B>[m
393-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.RenderLoginPage(c, a)<U+001B>[m
394-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
395-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/login/:provider", func(c echo.Context) error {<U+001B>[m
396-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.StartOAuth(c, a)<U+001B>[m
397-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
398-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(a.OauthCallbackURL, func(c echo.Context) error {<U+001B>[m
399-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.OAuthCallback(c, a)<U+001B>[m
400-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
401-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/logout", func(c echo.Context) error {<U+001B>[m
402-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.Logout(c, a)<U+001B>[m
403-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
404-<U+001B>[32m+<U+001B>[m<U+001B>[32m}<U+001B>[m
@@ -1,404 +0,0 @@
1-<U+001B>[1mdiff --git a/changes.txt b/changes.txt<U+001B>[m
2-<U+001B>[1mdeleted file mode 100644<U+001B>[m
3-<U+001B>[1mindex ab78b90..0000000<U+001B>[m
4-<U+001B>[1m--- a/changes.txt<U+001B>[m
5-<U+001B>[1m+++ /dev/null<U+001B>[m
6-<U+001B>[36m@@ -1,326 +0,0 @@<U+001B>[m
7-<U+001B>[31m-diff --git a/:memory b/:memory<U+001B>[m
8-<U+001B>[31m-new file mode 100644<U+001B>[m
9-<U+001B>[31m-index 0000000..9760229<U+001B>[m
10-<U+001B>[31m-Binary files /dev/null and b/:memory differ<U+001B>[m
11-<U+001B>[31m-diff --git a/cmd/main.go b/cmd/main.go<U+001B>[m
12-<U+001B>[31m-index 6a95d32..b8e2cd4 100644<U+001B>[m
13-<U+001B>[31m---- a/cmd/main.go<U+001B>[m
14-<U+001B>[31m-+++ b/cmd/main.go<U+001B>[m
15-<U+001B>[31m-@@ -4,17 +4,30 @@ import (<U+001B>[m
16-<U+001B>[31m- "fmt"<U+001B>[m
17-<U+001B>[31m- "log/slog"<U+001B>[m
18-<U+001B>[31m- <U+001B>[m
19-<U+001B>[31m-+ "github.com/labstack/echo/v4"<U+001B>[m
20-<U+001B>[31m-+<U+001B>[m
21-<U+001B>[31m- "github.com/bnema/gordon/internal/app"<U+001B>[m
22-<U+001B>[31m- "github.com/bnema/gordon/internal/httpserve"<U+001B>[m
23-<U+001B>[31m-- "github.com/labstack/echo/v4"<U+001B>[m
24-<U+001B>[31m- )<U+001B>[m
25-<U+001B>[31m- <U+001B>[m
26-<U+001B>[31m- func main() {<U+001B>[m
27-<U+001B>[31m- a := app.NewApp()<U+001B>[m
28-<U+001B>[31m-+<U+001B>[m
29-<U+001B>[31m-+ // Initialize database<U+001B>[m
30-<U+001B>[31m-+ db, err := app.InitializeDB(a)<U+001B>[m
31-<U+001B>[31m-+ if err != nil {<U+001B>[m
32-<U+001B>[31m-+ slog.Error("Failed to load database", err)<U+001B>[m
33-<U+001B>[31m-+ } else {<U+001B>[m
34-<U+001B>[31m-+ slog.Info("Database loaded")<U+001B>[m
35-<U+001B>[31m-+ }<U+001B>[m
36-<U+001B>[31m-+<U+001B>[m
37-<U+001B>[31m-+ fmt.Println(db)<U+001B>[m
38-<U+001B>[31m-+<U+001B>[m
39-<U+001B>[31m- e := echo.New()<U+001B>[m
40-<U+001B>[31m- e.HideBanner = true<U+001B>[m
41-<U+001B>[31m- e.HidePort = true<U+001B>[m
42-<U+001B>[31m- e = httpserve.RegisterRoutes(e, a)<U+001B>[m
43-<U+001B>[31m- slog.Info("Starting server", "port", a.HttpPort)<U+001B>[m
44-<U+001B>[31m- slog.Error("Server error", e.Start(fmt.Sprintf(":%d", a.HttpPort)))<U+001B>[m
45-<U+001B>[31m-+<U+001B>[m
46-<U+001B>[31m- }<U+001B>[m
47-<U+001B>[31m-diff --git a/go.mod b/go.mod<U+001B>[m
48-<U+001B>[31m-index 35e2d3c..8a3ac59 100644<U+001B>[m
49-<U+001B>[31m---- a/go.mod<U+001B>[m
50-<U+001B>[31m-+++ b/go.mod<U+001B>[m
51-<U+001B>[31m-@@ -24,6 +24,7 @@ require (<U+001B>[m
52-<U+001B>[31m- github.com/gorilla/securecookie v1.1.1 // indirect<U+001B>[m
53-<U+001B>[31m- github.com/gorilla/sessions v1.2.1 // indirect<U+001B>[m
54-<U+001B>[31m- github.com/klauspost/compress v1.16.7 // indirect<U+001B>[m
55-<U+001B>[31m-+ github.com/kr/text v0.1.0 // indirect<U+001B>[m
56-<U+001B>[31m- github.com/labstack/gommon v0.4.0 // indirect<U+001B>[m
57-<U+001B>[31m- github.com/mattn/go-colorable v0.1.13 // indirect<U+001B>[m
58-<U+001B>[31m- github.com/mattn/go-isatty v0.0.19 // indirect<U+001B>[m
59-<U+001B>[31m-@@ -35,6 +36,7 @@ require (<U+001B>[m
60-<U+001B>[31m- github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect<U+001B>[m
61-<U+001B>[31m- github.com/opencontainers/runc v1.1.9 // indirect<U+001B>[m
62-<U+001B>[31m- github.com/pkg/errors v0.9.1 // indirect<U+001B>[m
63-<U+001B>[31m-+ github.com/rogpeppe/go-internal v1.11.0 // indirect<U+001B>[m
64-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3 // indirect<U+001B>[m
65-<U+001B>[31m- github.com/valyala/bytebufferpool v1.0.0 // indirect<U+001B>[m
66-<U+001B>[31m- github.com/valyala/fasttemplate v1.2.2 // indirect<U+001B>[m
67-<U+001B>[31m-@@ -45,5 +47,6 @@ require (<U+001B>[m
68-<U+001B>[31m- golang.org/x/text v0.11.0 // indirect<U+001B>[m
69-<U+001B>[31m- golang.org/x/time v0.3.0 // indirect<U+001B>[m
70-<U+001B>[31m- golang.org/x/tools v0.7.0 // indirect<U+001B>[m
71-<U+001B>[31m-+ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect<U+001B>[m
72-<U+001B>[31m- gotest.tools/v3 v3.5.0 // indirect<U+001B>[m
73-<U+001B>[31m- )<U+001B>[m
74-<U+001B>[31m-diff --git a/go.sum b/go.sum<U+001B>[m
75-<U+001B>[31m-index 7b9b857..17b0bcd 100644<U+001B>[m
76-<U+001B>[31m---- a/go.sum<U+001B>[m
77-<U+001B>[31m-+++ b/go.sum<U+001B>[m
78-<U+001B>[31m-@@ -39,6 +39,11 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI<U+001B>[m
79-<U+001B>[31m- github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=<U+001B>[m
80-<U+001B>[31m- github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=<U+001B>[m
81-<U+001B>[31m- github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=<U+001B>[m
82-<U+001B>[31m-+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=<U+001B>[m
83-<U+001B>[31m-+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=<U+001B>[m
84-<U+001B>[31m-+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=<U+001B>[m
85-<U+001B>[31m-+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=<U+001B>[m
86-<U+001B>[31m-+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=<U+001B>[m
87-<U+001B>[31m- github.com/labstack/echo-contrib v0.15.0 h1:9K+oRU265y4Mu9zpRDv3X+DGTqUALY6oRHCSZZKCRVU=<U+001B>[m
88-<U+001B>[31m- github.com/labstack/echo-contrib v0.15.0/go.mod h1:lei+qt5CLB4oa7VHTE0yEfQSEB9XTJI1LUqko9UWvo4=<U+001B>[m
89-<U+001B>[31m- github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4=<U+001B>[m
90-<U+001B>[31m-@@ -72,6 +77,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=<U+001B>[m
91-<U+001B>[31m- github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=<U+001B>[m
92-<U+001B>[31m- github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=<U+001B>[m
93-<U+001B>[31m- github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=<U+001B>[m
94-<U+001B>[31m-+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=<U+001B>[m
95-<U+001B>[31m-+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=<U+001B>[m
96-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=<U+001B>[m
97-<U+001B>[31m- github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=<U+001B>[m
98-<U+001B>[31m- github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=<U+001B>[m
99-<U+001B>[31m-@@ -153,8 +160,9 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T<U+001B>[m
100-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
101-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
102-<U+001B>[31m- golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=<U+001B>[m
103-<U+001B>[31m--gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=<U+001B>[m
104-<U+001B>[31m- gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=<U+001B>[m
105-<U+001B>[31m-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=<U+001B>[m
106-<U+001B>[31m-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=<U+001B>[m
107-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=<U+001B>[m
108-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=<U+001B>[m
109-<U+001B>[31m- gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=<U+001B>[m
110-<U+001B>[31m-diff --git a/internal/app/app.go b/internal/app/app.go<U+001B>[m
111-<U+001B>[31m-index c6f49ac..1dd44b8 100644<U+001B>[m
112-<U+001B>[31m---- a/internal/app/app.go<U+001B>[m
113-<U+001B>[31m-+++ b/internal/app/app.go<U+001B>[m
114-<U+001B>[31m-@@ -27,6 +27,7 @@ const (<U+001B>[m
115-<U+001B>[31m- type App struct {<U+001B>[m
116-<U+001B>[31m- TemplateFS fs.FS<U+001B>[m
117-<U+001B>[31m- PublicFS fs.FS<U+001B>[m
118-<U+001B>[31m-+ DB interface{}<U+001B>[m
119-<U+001B>[31m- BuildVersion string<U+001B>[m
120-<U+001B>[31m- BuildDir string<U+001B>[m
121-<U+001B>[31m- DBDir string<U+001B>[m
122-<U+001B>[31m-diff --git a/internal/app/sqlite.go b/internal/app/sqlite.go<U+001B>[m
123-<U+001B>[31m-index 9f1b1ab..ddc6a1e 100644<U+001B>[m
124-<U+001B>[31m---- a/internal/app/sqlite.go<U+001B>[m
125-<U+001B>[31m-+++ b/internal/app/sqlite.go<U+001B>[m
126-<U+001B>[31m-@@ -5,58 +5,78 @@ import (<U+001B>[m
127-<U+001B>[31m- "database/sql"<U+001B>[m
128-<U+001B>[31m- "fmt"<U+001B>[m
129-<U+001B>[31m- "os"<U+001B>[m
130-<U+001B>[31m-+ "path/filepath"<U+001B>[m
131-<U+001B>[31m- <U+001B>[m
132-<U+001B>[31m-- sqlite3 "github.com/mattn/go-sqlite3"<U+001B>[m
133-<U+001B>[31m-+ "github.com/bnema/gordon/internal/database/migrate"<U+001B>[m
134-<U+001B>[31m-+ "github.com/mattn/go-sqlite3"<U+001B>[m
135-<U+001B>[31m- )<U+001B>[m
136-<U+001B>[31m- <U+001B>[m
137-<U+001B>[31m--// Initialize in-memory SQLite database and returns its connection<U+001B>[m
138-<U+001B>[31m--func InitDB() (db *sql.DB, err error) {<U+001B>[m
139-<U+001B>[31m-- db, err = sql.Open("sqlite3", "file::memory?cache=shared")<U+001B>[m
140-<U+001B>[31m-- if err != nil {<U+001B>[m
141-<U+001B>[31m-- return nil, fmt.Errorf("failed to open in-memory database: %v", err)<U+001B>[m
142-<U+001B>[31m-- }<U+001B>[m
143-<U+001B>[31m-- return<U+001B>[m
144-<U+001B>[31m--}<U+001B>[m
145-<U+001B>[31m--<U+001B>[m
146-<U+001B>[31m--// CloseDB closes the database connection and backs up the in-memory database to disk<U+001B>[m
147-<U+001B>[31m--func CloseDB(db *sql.DB, a *App) error {<U+001B>[m
148-<U+001B>[31m-- if err := BackupDB(db, a); err != nil {<U+001B>[m
149-<U+001B>[31m-- return err<U+001B>[m
150-<U+001B>[31m-- }<U+001B>[m
151-<U+001B>[31m-+// InitializeDB initializes the SQLite database. If a database file exists on disk, it loads it into memory.<U+001B>[m
152-<U+001B>[31m-+// Otherwise, it creates a new in-memory database and bootstraps it.<U+001B>[m
153-<U+001B>[31m-+func InitializeDB(a *App) (*sql.DB, error) {<U+001B>[m
154-<U+001B>[31m-+ dbfp := a.GetDBFilePath()<U+001B>[m
155-<U+001B>[31m- <U+001B>[m
156-<U+001B>[31m-- if err := db.Close(); err != nil {<U+001B>[m
157-<U+001B>[31m-- return fmt.Errorf("failed to close database: %v", err)<U+001B>[m
158-<U+001B>[31m-+ // Check if the directory exists, if not create it<U+001B>[m
159-<U+001B>[31m-+ dir := filepath.Dir(a.DBDir)<U+001B>[m
160-<U+001B>[31m-+ fmt.Println("dir", dir)<U+001B>[m
161-<U+001B>[31m-+ if _, err := os.Stat(dir); os.IsNotExist(err) {<U+001B>[m
162-<U+001B>[31m-+ err = os.MkdirAll(dir, 0755)<U+001B>[m
163-<U+001B>[31m-+ if err != nil {<U+001B>[m
164-<U+001B>[31m-+ return nil, fmt.Errorf("failed to create directory: %v", err)<U+001B>[m
165-<U+001B>[31m-+ }<U+001B>[m
166-<U+001B>[31m- }<U+001B>[m
167-<U+001B>[31m- <U+001B>[m
168-<U+001B>[31m-- return nil<U+001B>[m
169-<U+001B>[31m--}<U+001B>[m
170-<U+001B>[31m-+ // If the database file doesn't exist on disk<U+001B>[m
171-<U+001B>[31m-+ if _, err := os.Stat(dbfp); os.IsNotExist(err) {<U+001B>[m
172-<U+001B>[31m-+ memDB, err := initInMemoryDB()<U+001B>[m
173-<U+001B>[31m-+ if err != nil {<U+001B>[m
174-<U+001B>[31m-+ return nil, err<U+001B>[m
175-<U+001B>[31m-+ }<U+001B>[m
176-<U+001B>[31m- <U+001B>[m
177-<U+001B>[31m--// LoadDBIntoMemory loads the database from disk into memory<U+001B>[m
178-<U+001B>[31m--func LoadDBIntoMemory(a *App) (*sql.DB, error) {<U+001B>[m
179-<U+001B>[31m-- dbfp := a.GetDBFilePath()<U+001B>[m
180-<U+001B>[31m-+ // Run the bootstrap<U+001B>[m
181-<U+001B>[31m-+ RunBootstrap(memDB)<U+001B>[m
182-<U+001B>[31m- <U+001B>[m
183-<U+001B>[31m-- if _, err := os.Stat(dbfp); err != nil {<U+001B>[m
184-<U+001B>[31m-- return nil, nil<U+001B>[m
185-<U+001B>[31m-+ // Explicitly backup the in-memory database to disk<U+001B>[m
186-<U+001B>[31m-+ err = BackupDB(memDB, a)<U+001B>[m
187-<U+001B>[31m-+ if err != nil {<U+001B>[m
188-<U+001B>[31m-+ return nil, fmt.Errorf("failed to backup in-memory database to disk: %v", err)<U+001B>[m
189-<U+001B>[31m-+ }<U+001B>[m
190-<U+001B>[31m- }<U+001B>[m
191-<U+001B>[31m- <U+001B>[m
192-<U+001B>[31m-- memDB, err := InitDB()<U+001B>[m
193-<U+001B>[31m-+ memDB, err := initInMemoryDB()<U+001B>[m
194-<U+001B>[31m- if err != nil {<U+001B>[m
195-<U+001B>[31m- return nil, err<U+001B>[m
196-<U+001B>[31m- }<U+001B>[m
197-<U+001B>[31m--<U+001B>[m
198-<U+001B>[31m- diskDB, err := sql.Open("sqlite3", dbfp)<U+001B>[m
199-<U+001B>[31m- if err != nil {<U+001B>[m
200-<U+001B>[31m- return nil, fmt.Errorf("failed to open database file: %v", err)<U+001B>[m
201-<U+001B>[31m- }<U+001B>[m
202-<U+001B>[31m-+ defer diskDB.Close()<U+001B>[m
203-<U+001B>[31m- <U+001B>[m
204-<U+001B>[31m- if err := transferData(diskDB, memDB); err != nil {<U+001B>[m
205-<U+001B>[31m- return nil, err<U+001B>[m
206-<U+001B>[31m- }<U+001B>[m
207-<U+001B>[31m--<U+001B>[m
208-<U+001B>[31m- return memDB, nil<U+001B>[m
209-<U+001B>[31m- }<U+001B>[m
210-<U+001B>[31m- <U+001B>[m
211-<U+001B>[31m--// transferData transfers data from srcDB to dstDB<U+001B>[m
212-<U+001B>[31m-+func initInMemoryDB() (*sql.DB, error) {<U+001B>[m
213-<U+001B>[31m-+ db, err := sql.Open("sqlite3", "file::memory?cache=shared")<U+001B>[m
214-<U+001B>[31m-+ if err != nil {<U+001B>[m
215-<U+001B>[31m-+ return nil, fmt.Errorf("failed to open in-memory database: %v", err)<U+001B>[m
216-<U+001B>[31m-+ }<U+001B>[m
217-<U+001B>[31m-+ return db, nil<U+001B>[m
218-<U+001B>[31m-+}<U+001B>[m
219-<U+001B>[31m-+<U+001B>[m
220-<U+001B>[31m-+func CloseAndBackupDB(db *sql.DB, a *App) error {<U+001B>[m
221-<U+001B>[31m-+ if err := BackupDB(db, a); err != nil {<U+001B>[m
222-<U+001B>[31m-+ return err<U+001B>[m
223-<U+001B>[31m-+ }<U+001B>[m
224-<U+001B>[31m-+ if err := db.Close(); err != nil {<U+001B>[m
225-<U+001B>[31m-+ return fmt.Errorf("failed to close database: %v", err)<U+001B>[m
226-<U+001B>[31m-+ }<U+001B>[m
227-<U+001B>[31m-+ return nil<U+001B>[m
228-<U+001B>[31m-+}<U+001B>[m
229-<U+001B>[31m-+<U+001B>[m
230-<U+001B>[31m- func transferData(srcDB, dstDB *sql.DB) error {<U+001B>[m
231-<U+001B>[31m- srcConn, err := srcDB.Conn(context.Background())<U+001B>[m
232-<U+001B>[31m- if err != nil {<U+001B>[m
233-<U+001B>[31m-@@ -74,35 +94,50 @@ func transferData(srcDB, dstDB *sql.DB) error {<U+001B>[m
234-<U+001B>[31m- return dstConn.Raw(func(dstRawConn interface{}) error {<U+001B>[m
235-<U+001B>[31m- srcSqlite3Conn := srcRawConn.(*sqlite3.SQLiteConn)<U+001B>[m
236-<U+001B>[31m- dstSqlite3Conn := dstRawConn.(*sqlite3.SQLiteConn)<U+001B>[m
237-<U+001B>[31m--<U+001B>[m
238-<U+001B>[31m- _, err := srcSqlite3Conn.Backup("main", dstSqlite3Conn, "main")<U+001B>[m
239-<U+001B>[31m- return err<U+001B>[m
240-<U+001B>[31m- })<U+001B>[m
241-<U+001B>[31m- })<U+001B>[m
242-<U+001B>[31m- }<U+001B>[m
243-<U+001B>[31m- <U+001B>[m
244-<U+001B>[31m--// BackupDB backs up the in-memory database to disk<U+001B>[m
245-<U+001B>[31m- func BackupDB(db *sql.DB, a *App) error {<U+001B>[m
246-<U+001B>[31m- dbfp := a.GetDBFilePath()<U+001B>[m
247-<U+001B>[31m--<U+001B>[m
248-<U+001B>[31m- conn, err := db.Conn(context.Background())<U+001B>[m
249-<U+001B>[31m- if err != nil {<U+001B>[m
250-<U+001B>[31m- return fmt.Errorf("failed to get underlying database connection: %v", err)<U+001B>[m
251-<U+001B>[31m- }<U+001B>[m
252-<U+001B>[31m-+ defer conn.Close()<U+001B>[m
253-<U+001B>[31m- <U+001B>[m
254-<U+001B>[31m- return conn.Raw(func(sqliteConn interface{}) error {<U+001B>[m
255-<U+001B>[31m- sqlite3Conn := sqliteConn.(*sqlite3.SQLiteConn)<U+001B>[m
256-<U+001B>[31m-- backupDB, err := sqlite3Conn.Backup(dbfp, sqlite3Conn, "main")<U+001B>[m
257-<U+001B>[31m-+ diskDB, err := sql.Open("sqlite3", dbfp)<U+001B>[m
258-<U+001B>[31m-+ fmt.Println("diskDB", diskDB)<U+001B>[m
259-<U+001B>[31m-+ if err != nil {<U+001B>[m
260-<U+001B>[31m-+ return fmt.Errorf("failed to open destination database file: %v", err)<U+001B>[m
261-<U+001B>[31m-+ }<U+001B>[m
262-<U+001B>[31m-+ defer diskDB.Close()<U+001B>[m
263-<U+001B>[31m-+<U+001B>[m
264-<U+001B>[31m-+ diskConn, err := diskDB.Conn(context.Background())<U+001B>[m
265-<U+001B>[31m- if err != nil {<U+001B>[m
266-<U+001B>[31m-- return fmt.Errorf("failed to create backup: %v", err)<U+001B>[m
267-<U+001B>[31m-+ return fmt.Errorf("failed to get connection from diskDB: %v", err)<U+001B>[m
268-<U+001B>[31m- }<U+001B>[m
269-<U+001B>[31m-+ defer diskConn.Close()<U+001B>[m
270-<U+001B>[31m-+<U+001B>[m
271-<U+001B>[31m-+ var backupDB *sqlite3.SQLiteBackup<U+001B>[m
272-<U+001B>[31m-+ err = diskConn.Raw(func(diskRawConn interface{}) error {<U+001B>[m
273-<U+001B>[31m-+ backupDB, err = sqlite3Conn.Backup("main", diskRawConn.(*sqlite3.SQLiteConn), "main")<U+001B>[m
274-<U+001B>[31m-+ return err<U+001B>[m
275-<U+001B>[31m-+ })<U+001B>[m
276-<U+001B>[31m- defer backupDB.Close()<U+001B>[m
277-<U+001B>[31m- <U+001B>[m
278-<U+001B>[31m- _, err = backupDB.Step(-1)<U+001B>[m
279-<U+001B>[31m- if err != nil {<U+001B>[m
280-<U+001B>[31m- return fmt.Errorf("failed to backup in-memory database: %v", err)<U+001B>[m
281-<U+001B>[31m- }<U+001B>[m
282-<U+001B>[31m--<U+001B>[m
283-<U+001B>[31m- return nil<U+001B>[m
284-<U+001B>[31m- })<U+001B>[m
285-<U+001B>[31m- }<U+001B>[m
286-<U+001B>[31m-+<U+001B>[m
287-<U+001B>[31m-+func RunBootstrap(db *sql.DB) error {<U+001B>[m
288-<U+001B>[31m-+ return migrate.CreateUserTable(db)<U+001B>[m
289-<U+001B>[31m-+}<U+001B>[m
290-<U+001B>[31m-diff --git a/internal/database/migrate/bootstrapdb.go b/internal/database/migrate/bootstrapdb.go<U+001B>[m
291-<U+001B>[31m-new file mode 100644<U+001B>[m
292-<U+001B>[31m-index 0000000..1f53246<U+001B>[m
293-<U+001B>[31m---- /dev/null<U+001B>[m
294-<U+001B>[31m-+++ b/internal/database/migrate/bootstrapdb.go<U+001B>[m
295-<U+001B>[31m-@@ -0,0 +1,24 @@<U+001B>[m
296-<U+001B>[31m-+package migrate<U+001B>[m
297-<U+001B>[31m-+<U+001B>[m
298-<U+001B>[31m-+import (<U+001B>[m
299-<U+001B>[31m-+ "database/sql"<U+001B>[m
300-<U+001B>[31m-+ "fmt"<U+001B>[m
301-<U+001B>[31m-+)<U+001B>[m
302-<U+001B>[31m-+<U+001B>[m
303-<U+001B>[31m-+// createUserTable creates the 'user' table in the provided SQLite database.<U+001B>[m
304-<U+001B>[31m-+func CreateUserTable(db *sql.DB) error {<U+001B>[m
305-<U+001B>[31m-+ createTableSQL := `<U+001B>[m
306-<U+001B>[31m-+ CREATE TABLE user (<U+001B>[m
307-<U+001B>[31m-+ id INTEGER PRIMARY KEY AUTOINCREMENT,<U+001B>[m
308-<U+001B>[31m-+ username TEXT NOT NULL,<U+001B>[m
309-<U+001B>[31m-+ password TEXT NOT NULL, -- This should be hashed and salted in a real-world scenario.<U+001B>[m
310-<U+001B>[31m-+ oauth_token TEXT<U+001B>[m
311-<U+001B>[31m-+ );`<U+001B>[m
312-<U+001B>[31m-+<U+001B>[m
313-<U+001B>[31m-+ _, err := db.Exec(createTableSQL)<U+001B>[m
314-<U+001B>[31m-+ if err != nil {<U+001B>[m
315-<U+001B>[31m-+ return fmt.Errorf("failed to create user table: %v", err)<U+001B>[m
316-<U+001B>[31m-+ }<U+001B>[m
317-<U+001B>[31m-+<U+001B>[m
318-<U+001B>[31m-+ return nil<U+001B>[m
319-<U+001B>[31m-+}<U+001B>[m
320-<U+001B>[31m-diff --git a/internal/httpserve/handler/adminroutes.go b/internal/httpserve/handler/adminroutes.go<U+001B>[m
321-<U+001B>[31m-index 8701ae3..f4acd64 100644<U+001B>[m
322-<U+001B>[31m---- a/internal/httpserve/handler/adminroutes.go<U+001B>[m
323-<U+001B>[31m-+++ b/internal/httpserve/handler/adminroutes.go<U+001B>[m
324-<U+001B>[31m-@@ -1,8 +1,6 @@<U+001B>[m
325-<U+001B>[31m- package handler<U+001B>[m
326-<U+001B>[31m- <U+001B>[m
327-<U+001B>[31m- import (<U+001B>[m
328-<U+001B>[31m-- "fmt"<U+001B>[m
329-<U+001B>[31m--<U+001B>[m
330-<U+001B>[31m- "github.com/bnema/gordon/internal/app"<U+001B>[m
331-<U+001B>[31m- "github.com/bnema/gordon/internal/gotemplate/render"<U+001B>[m
332-<U+001B>[31m- "github.com/bnema/gordon/internal/httpserve/middleware"<U+001B>[m
333-<U+001B>[1mdiff --git a/internal/httpserve/handler/oauth.go b/internal/httpserve/handler/oauth.go<U+001B>[m
334-<U+001B>[1mindex bd40379..b876c75 100644<U+001B>[m
335-<U+001B>[1m--- a/internal/httpserve/handler/oauth.go<U+001B>[m
336-<U+001B>[1m+++ b/internal/httpserve/handler/oauth.go<U+001B>[m
337-<U+001B>[36m@@ -12,6 +12,7 @@<U+001B>[m <U+001B>[mimport (<U+001B>[m
338- "github.com/markbates/goth/gothic"<U+001B>[m
339- "github.com/markbates/goth/providers/github"<U+001B>[m
340- "net/http"<U+001B>[m
341-<U+001B>[32m+<U+001B>[m <U+001B>[32m"os"<U+001B>[m
342- )<U+001B>[m
343- <U+001B>[m
344- var providerNames []string<U+001B>[m
345-<U+001B>[1mdiff --git a/internal/httpserve/router.go b/internal/httpserve/router.go<U+001B>[m
346-<U+001B>[1mindex bc1368c..edd2748 100644<U+001B>[m
347-<U+001B>[1m--- a/internal/httpserve/router.go<U+001B>[m
348-<U+001B>[1m+++ b/internal/httpserve/router.go<U+001B>[m
349-<U+001B>[36m@@ -19,34 +19,19 @@<U+001B>[m <U+001B>[mfunc RegisterRoutes(e *echo.Echo, a *app.App) *echo.Echo {<U+001B>[m
350- // Use session middleware<U+001B>[m
351- // Add session middleware<U+001B>[m
352- e.Use(session.Middleware(sessions.NewCookieStore([]byte(os.Getenv("SECRET")))))<U+001B>[m
353-<U+001B>[31m- // e.Use(middleware.SecureRoutes())<U+001B>[m
354- e.Use(middleware.ColorSchemeDetection)<U+001B>[m
355- e.Use(middleware.LanguageDetection)<U+001B>[m
356- <U+001B>[m
357- // Register routes<U+001B>[m
358-<U+001B>[31m-<U+001B>[m
359-<U+001B>[31m- // Serve admin routes<U+001B>[m
360- bindAdminRoute(e, a, AdminPath)<U+001B>[m
361-<U+001B>[31m- // Serve static files<U+001B>[m
362- bindStaticRoute(e, a, "/*")<U+001B>[m
363-<U+001B>[32m+<U+001B>[m <U+001B>[32mbindLoginRoute(e, a, AdminPath)<U+001B>[m
364-<U+001B>[32m+<U+001B>[m
365- // Protect the root path with a 403<U+001B>[m
366- e.GET("/", func(c echo.Context) error {<U+001B>[m
367- return c.String(403, "403 Forbidden")<U+001B>[m
368- })<U+001B>[m
369- <U+001B>[m
370-<U+001B>[31m- e.GET(a.AdminPath+"/login", func(c echo.Context) error {<U+001B>[m
371-<U+001B>[31m- return handler.RenderLoginPage(c, a)<U+001B>[m
372-<U+001B>[31m- })<U+001B>[m
373-<U+001B>[31m- e.GET(a.AdminPath+"/login/:provider", func(c echo.Context) error {<U+001B>[m
374-<U+001B>[31m- return handler.StartOAuth(c, a)<U+001B>[m
375-<U+001B>[31m- })<U+001B>[m
376-<U+001B>[31m- e.GET(a.OauthCallbackURL, func(c echo.Context) error {<U+001B>[m
377-<U+001B>[31m- return handler.OAuthCallback(c, a)<U+001B>[m
378-<U+001B>[31m- })<U+001B>[m
379-<U+001B>[31m- e.GET(a.AdminPath+"/logout", func(c echo.Context) error {<U+001B>[m
380-<U+001B>[31m- return handler.Logout(c, a)<U+001B>[m
381-<U+001B>[31m- })<U+001B>[m
382-<U+001B>[31m-<U+001B>[m
383- return e<U+001B>[m
384- }<U+001B>[m
385- <U+001B>[m
386-<U+001B>[36m@@ -61,3 +46,18 @@<U+001B>[m <U+001B>[mfunc bindAdminRoute(e *echo.Echo, a *app.App, path string) {<U+001B>[m
387- return handler.AdminRoute(c, a)<U+001B>[m
388- })<U+001B>[m
389- }<U+001B>[m
390-<U+001B>[32m+<U+001B>[m
391-<U+001B>[32m+<U+001B>[m<U+001B>[32mfunc bindLoginRoute(e *echo.Echo, a *app.App, adminPath string) {<U+001B>[m
392-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/login", func(c echo.Context) error {<U+001B>[m
393-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.RenderLoginPage(c, a)<U+001B>[m
394-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
395-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/login/:provider", func(c echo.Context) error {<U+001B>[m
396-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.StartOAuth(c, a)<U+001B>[m
397-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
398-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(a.OauthCallbackURL, func(c echo.Context) error {<U+001B>[m
399-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.OAuthCallback(c, a)<U+001B>[m
400-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
401-<U+001B>[32m+<U+001B>[m <U+001B>[32me.GET(adminPath+"/logout", func(c echo.Context) error {<U+001B>[m
402-<U+001B>[32m+<U+001B>[m <U+001B>[32mreturn handler.Logout(c, a)<U+001B>[m
403-<U+001B>[32m+<U+001B>[m <U+001B>[32m})<U+001B>[m
404-<U+001B>[32m+<U+001B>[m<U+001B>[32m}<U+001B>[m

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close