From 378269dadf05854e4695c5608d725007028f489f Mon Sep 17 00:00:00 2001 From: Leonardo Mello Date: Thu, 30 Mar 2023 10:58:57 -0300 Subject: [PATCH] Add `notebook` configuration to set default notebook path --- docs/config.md | 5 ++++ docs/notebook.md | 2 ++ internal/cli/container.go | 17 ++++++++++++ internal/core/config.go | 52 +++++++++++++++++++++++++----------- internal/core/config_test.go | 9 +++++++ 5 files changed, 69 insertions(+), 16 deletions(-) diff --git a/docs/config.md b/docs/config.md index 81a0bc67..5b49be9e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2,6 +2,7 @@ Each [notebook](notebook.md) contains a configuration file used to customize your experience with `zk`. This file is located at `.zk/config.toml` and uses the [TOML format](https://github.com/toml-lang/toml). It is composed of several optional sections: +* `[notebook]` sets the [notebook rules](config-notebook.md) * `[note]` sets the [note creation rules](config-note.md) * `[extra]` contains free [user variables](config-extra.md) which can be expanded in templates * `[group]` defines [note groups](config-group.md) with custom rules @@ -26,6 +27,10 @@ Notebook configuration files will inherit the settings defined in the global con Here's an example of a complete configuration file: ```toml +# NOTEBOOK SETTINGS +[notebook] +dir = "~/notebook" + # NOTE SETTINGS [note] diff --git a/docs/notebook.md b/docs/notebook.md index 4b02c735..bdda17bc 100644 --- a/docs/notebook.md +++ b/docs/notebook.md @@ -6,6 +6,8 @@ To create a new notebook, simply run `zk init []`. Most `zk` commands are operating "Git-style" on the notebook containing the current working directory (or one of its parents). However, you can explicitly set which notebook to use with `--notebook-dir` or the `ZK_NOTEBOOK_DIR` environment variable. Setting `ZK_NOTEBOOK_DIR` in your shell configuration (e.g. `~/.profile`) can be used to define a default notebook which `zk` commands will use when the working directory is not in another notebook. +If the [default notebook](config-notebook.md) is set it will be used as `ZK_NOTEBOOK_DIR`, unless this environment variable is not already set. + ## Anatomy of a notebook Similarly to Git, a notebook is identified by the presence of a `.zk` directory at its root. This directory contains the only `zk`-specific files in your notebook: diff --git a/internal/cli/container.go b/internal/cli/container.go index eb19085c..20255fe6 100644 --- a/internal/cli/container.go +++ b/internal/cli/container.go @@ -4,6 +4,7 @@ import ( "io" "os" "path/filepath" + "strings" "github.com/mickael-menu/zk/internal/adapter/editor" "github.com/mickael-menu/zk/internal/adapter/fs" @@ -71,6 +72,22 @@ func NewContainer(version string) (*Container, error) { } } + // Set the default notebook if not already set + // might be overrided if --notebook-dir flag is present + if osutil.GetOptEnv("ZK_NOTEBOOK_DIR").IsNull() && !config.Notebook.Dir.IsNull() { + // Expand in case there are environment variables on the path + notebookDir := os.Expand(config.Notebook.Dir.Unwrap(), os.Getenv) + if strings.HasPrefix(notebookDir, "~") { + dirname, err := os.UserHomeDir() + if err != nil { + return nil, wrap(err) + } + notebookDir = filepath.Join(dirname, notebookDir[1:]) + } + os.Setenv("ZK_NOTEBOOK_DIR", notebookDir) + // TODO: docs about environment variables and ~/ + } + // Set the default shell if not already set if osutil.GetOptEnv("ZK_SHELL").IsNull() && !config.Tool.Shell.IsEmpty() { os.Setenv("ZK_SHELL", config.Tool.Shell.Unwrap()) diff --git a/internal/core/config.go b/internal/core/config.go index d6778dc0..96c47086 100644 --- a/internal/core/config.go +++ b/internal/core/config.go @@ -12,19 +12,23 @@ import ( // Config holds the user configuration. type Config struct { - Note NoteConfig - Groups map[string]GroupConfig - Format FormatConfig - Tool ToolConfig - LSP LSPConfig - Filters map[string]string - Aliases map[string]string - Extra map[string]string + Notebook NotebookConfig + Note NoteConfig + Groups map[string]GroupConfig + Format FormatConfig + Tool ToolConfig + LSP LSPConfig + Filters map[string]string + Aliases map[string]string + Extra map[string]string } // NewDefaultConfig creates a new Config with the default settings. func NewDefaultConfig() Config { return Config{ + Notebook: NotebookConfig{ + Dir: opt.NullString, + }, Note: NoteConfig{ FilenameTemplate: "{{id}}", Extension: "md", @@ -192,6 +196,11 @@ const ( LSPDiagnosticHint LSPDiagnosticSeverity = 4 ) +// NotebookConfig holds configuration about the default notebook +type NotebookConfig struct { + Dir opt.String +} + // NoteConfig holds the user configuration used when generating new notes. type NoteConfig struct { // Handlebars template used when generating a new filename. @@ -280,6 +289,12 @@ func ParseConfig(content []byte, path string, parentConfig Config) (Config, erro return config, wrap(err) } + // Notebook + notebook := tomlConf.Notebook + if notebook.Dir != "" { + config.Notebook.Dir = opt.NewNotEmptyString(notebook.Dir) + } + // Note note := tomlConf.Note if note.Filename != "" { @@ -472,14 +487,19 @@ func (c GroupConfig) merge(tomlConf tomlGroupConfig, name string) GroupConfig { // tomlConfig holds the TOML representation of Config type tomlConfig struct { - Note tomlNoteConfig - Groups map[string]tomlGroupConfig `toml:"group"` - Format tomlFormatConfig - Tool tomlToolConfig - LSP tomlLSPConfig - Extra map[string]string - Filters map[string]string `toml:"filter"` - Aliases map[string]string `toml:"alias"` + Notebook tomlNotebookConfig + Note tomlNoteConfig + Groups map[string]tomlGroupConfig `toml:"group"` + Format tomlFormatConfig + Tool tomlToolConfig + LSP tomlLSPConfig + Extra map[string]string + Filters map[string]string `toml:"filter"` + Aliases map[string]string `toml:"alias"` +} + +type tomlNotebookConfig struct { + Dir string } type tomlNoteConfig struct { diff --git a/internal/core/config_test.go b/internal/core/config_test.go index 2c534cf4..a15cbbfb 100644 --- a/internal/core/config_test.go +++ b/internal/core/config_test.go @@ -14,6 +14,9 @@ func TestParseDefaultConfig(t *testing.T) { assert.Nil(t, err) assert.Equal(t, conf, Config{ + Notebook: NotebookConfig{ + Dir: opt.NullString, + }, Note: NoteConfig{ FilenameTemplate: "{{id}}", Extension: "md", @@ -66,6 +69,9 @@ func TestParseComplete(t *testing.T) { conf, err := ParseConfig([]byte(` # Comment + [notebook] + dir = "~/notebook" + [note] filename = "{{id}}.note" extension = "txt" @@ -142,6 +148,9 @@ func TestParseComplete(t *testing.T) { assert.Nil(t, err) assert.Equal(t, conf, Config{ + Notebook: NotebookConfig{ + Dir: opt.NewString("~/notebook"), + }, Note: NoteConfig{ FilenameTemplate: "{{id}}.note", Extension: "txt",