Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

org_archive_location doesn't work with full paths #628

Closed
nicolasdumitru opened this issue Nov 10, 2023 · 5 comments
Closed

org_archive_location doesn't work with full paths #628

nicolasdumitru opened this issue Nov 10, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@nicolasdumitru
Copy link

Describe the bug

I tried to set the directory where files (or headings) get archived to a subdirectory called "archive" in my org files directory. It does not seem to work with absolut paths.

Steps to reproduce

Try to archive a headline.

Expected behavior

If HOME is the current user's home directory, the heading that you are trying to archive should get placed in ~/org/archive/<name_of_the_initial_file>.org_archive. Instead, it currently gets placed in ~/org/home/<your_user_name>/org/archive/<name_of_the_initial_file>.org_archive.

Emacs functionality

No response

Minimal init.lua

local org_directory = {}

org_directory.root = os.getenv("HOME") .. "/org/"
org_directory.archive = org_directory.root .. "archive/"

local function configuration()
	local org = require("orgmode")
	-- Load treesitter grammar for org
	org.setup_ts_grammar()

	-- Setup treesitter
	require("nvim-treesitter.configs").setup({
		highlight = {
			enable = true,
			additional_vim_regex_highlighting = { "org" },
		},
		ensure_installed = { "org" },
	})

	-- Setup orgmode
	org.setup({
		org_agenda_files = org_directory.root .. "**/*",
		org_default_notes_file = org_directory.root .. "refile.org",
		org_capture_templates = {
			-- TODO: add useful templates (maybe for backlog) and remove this one
			r = {
				description = "Repo",
				template = "* [[%x][%(return string.match('%x', '([^/]+)$'))]]%?",
				target = org_directory.root .. "repos.org",
			}
		},
		org_todo_keywords = { "TODO", "WAITING", "|", "DONE", "DELEGATED" },
		org_todo_keyword_faces = {
			WAITING = ":weight bold",
			DELEGATED = ":slant italic :underline on",
		},
		org_archive_location = org_directory.archive .. "%s_archive",
	})
end

local nvim_root = '/tmp/nvim_orgmode'
local lazy_root = nvim_root .. '/lazy'
local lazypath = lazy_root .. '/lazy.nvim'

-- Install lazy.nvim if not already installed
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    'git',
    'clone',
    '--filter=blob:none',
    'https://github.com/folke/lazy.nvim.git',
    '--branch=stable', -- latest stable release
    lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)

require('lazy').setup({
  {
    'nvim-orgmode/orgmode',
    dependencies = {
      { 'nvim-treesitter/nvim-treesitter', lazy = true },
    },
    event = 'VeryLazy',
    config = configuration,
  },
}, {
  root = lazy_root,
  lockfile = nvim_root .. '/lazy.json',
  install = {
    missing = false,
  },
})

require('lazy').sync({
  wait = true,
  show = false,
})

Screenshots and recordings

No response

OS / Distro

Arch Linux

Neovim version/commit

0.9.4 (build type: release; LuaJIT 2.1.1699392533

Additional context

No response

@nicolasdumitru nicolasdumitru added the bug Something isn't working label Nov 10, 2023
@Avimitin
Copy link

Get same error here. nvim-orgmode doesn't parse the string as a path, instead it will create a full path under the current directory.
image

@kristijanhusak
Copy link
Member

This should be fixed now. Let me know if it's still broken.

@nicolasdumitru
Copy link
Author

I'm sorry, but I won't test it, as I don't use this plugin anymore. I have started using it the original Org mode and Emacs (for and only for Org mode), despite the fact that I think Emacs itself is a steaming pile of hot garbage. The reason is threefold:

  • I need something that is fully functional ASAP.
  • There is a (real) ecosystem around Emacs Org mode (cool things like Org Roam)
  • I don't see why Org mode should be specific to one text editor or another. I might as well just use the more supported and popular original. There are also some subtle differences that I'd like to not have to account for.

I wish you and your project all the best!

@kristijanhusak
Copy link
Member

No worries, thanks for reporting the issue anyway.

@nicolasdumitru
Copy link
Author

Happy to help!

lyz-code added a commit to lyz-code/blue-book that referenced this issue Jan 8, 2024
[Activism](https://en.wikipedia.org/wiki/Activism) consists of efforts to promote, impede, direct or intervene in social, political, economic or environmental reform with the desire to make changes in society toward a perceived greater good.

feat(anki#What to do when you need to edit a card but don't have the time): What to do when you need to edit a card but don't have the time

You can mark it with a red flag so that you remember to edit it the next time you see it.

feat(bash_snippets#Show the progresion of a long running task with dots): Show the progresion of a long running task with dots

```bash
echo -n "Process X is running."

sleep 1
echo -n "."
sleep 1
echo -n "."

echo ""
```

feat(beancount#Comments): Comments

Any text on a line after the character `;` is ignored, text like this:

```beancount
; I paid and left the taxi, forgot to take change, it was cold.
2015-01-01 * "Taxi home from concert in Brooklyn"
  Assets:Cash      -20 USD  ; inline comment
  Expenses:Taxi
```

feat(boto3#Get running instances): Get running instances

```python
import boto3

ec2 = boto3.client('ec2')

running_instances = [
    instance
    for page in ec2.get_paginator('describe_instances').paginate()
    for reservation in page['Reservations']
    for instance in reservation['Instances']]
    if instance['State']['Name'] == 'running'
]
```

feat(castellano#El agua o la agua?): El agua o la agua?

El sustantivo agua es de género femenino, pero tiene la particularidad de comenzar por /a/ tónica (la vocal tónica de una palabra es aquella en la que recae el acento de intensidad: [água]). Por razones de fonética histórica, este tipo de palabras seleccionan en singular la forma `el` del artículo, en lugar de la forma femenina normal `la`. Esta regla solo opera cuando el artículo antecede inmediatamente al sustantivo, de ahí que digamos el agua, el área, el hacha; pero, si entre el artículo y el sustantivo se interpone otra palabra, la regla queda sin efecto, de ahí que digamos la misma agua, la extensa área, la afilada hacha. Puesto que estas palabras son femeninas, los adjetivos deben concordar siempre en femenino: el agua clara, el área extensa, el hacha afilada (y no el agua claro, el área extenso, el hacha afilado).

Por su parte, el indefinido `una` toma generalmente la forma `un` cuando antecede inmediatamente a sustantivos femeninos que comienzan por /a/ tónica: un área, un hacha, un águila (si bien no es incorrecto, aunque sí poco frecuente, utilizar la forma plena una: una área, una hacha, una águila). Asimismo, los indefinidos `alguna` y `ninguna` pueden adoptar en estos casos las formas apocopadas (algún alma, ningún alma) o mantener las formas plenas (alguna alma, ninguna alma).

Al tratarse de sustantivos femeninos, con los demostrativos este, ese, aquel o con cualquier otro adjetivo determinativo, como todo, mucho, poco, otro, etc., deben usarse las formas femeninas correspondientes: esta hacha, aquella misma arma, toda el agua, mucha hambre, etc. (y no este hacha, aquel mismo arma, todo el agua, mucho hambre, etc.)

feat(cleaning_tips): Cleaning car headlights

If you need to clean the car headlights you can use a mixture of one squeezed lemon and two spoonfuls of baking soda

feat(pydantic): Nicely show validation errors

A nice way of showing it is to capture the error and print it yourself:

```python
try:
    model = Model(
        state=state,
    )
except ValidationError as error:
    log.error(f'Error building model with state {state}')
    raise error
```

feat(pydantic#Load a pydantic model from json): Load a pydantic model from json

You can use the [`model_validate_json`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.main.BaseModel.model_validate_json) method that will validate and return an object with the loaded data.

```python
from datetime import date

from pydantic import BaseModel, ConfigDict, ValidationError

class Event(BaseModel):
    model_config = ConfigDict(strict=True)

    when: date
    where: tuple[int, int]

json_data = '{"when": "1987-01-28", "where": [51, -1]}'
print(Event.model_validate_json(json_data))

try:
    Event.model_validate({'when': '1987-01-28', 'where': [51, -1]})

except ValidationError as e:
    print(e)
    """
    2 validation errors for Event
    when
      Input should be a valid date [type=date_type, input_value='1987-01-28', input_type=str]
    where
      Input should be a valid tuple [type=tuple_type, input_value=[51, -1], input_type=list]
    """
```

feat(python_snippets#Get unique items between two lists): Get unique items between two lists

If you want all items from the second list that do not appear in the first list you can write:

```
x = [1,2,3,4]
f = [1,11,22,33,44,3,4]

result = set(f) - set(x)
```

feat(python_snippets#Pad number with zeros): Pad number with zeros

```python
number = 1
print(f"{number:02d}")
```

feat(kubernetes): Introduce IceKube

[IceKube](https://twitter.com/clintgibler/status/1732459956669214784) tool for finding complex attack paths in Kubernetes clusters. It's like Bloodhound for Kubernetes. It uses Neo4j to store & analyze Kubernetes resource relationships → identify attack paths & security misconfigs

feat(alertmanagerInhibit rules between times): Inhibit rules between times

To prevent some alerts to be sent between some hours you can use the `time_intervals` alertmanager configuration.

This can be useful for example if your backup system triggers some alerts that you don't need to act on.

```yaml
route:
  receiver: 'email'
  group_by: [job, alertname, severity]
  group_wait: 5m
  group_interval: 5m
  repeat_interval: 12h
  routes:
    - receiver: 'email'
      matchers:
        - alertname =~ "HostCpuHighIowait|HostContextSwitching|HostUnusualDiskWriteRate"
        - hostname = backup_server
      mute_time_intervals:
        - night
time_intervals:
  - name: night
    time_intervals:
      - times:
          - start_time: 02:00
            end_time: 07:00
```

feat(diccionario_galego): Add some galego vocabulary

feat(dino): Disable automatic OMEMO key acceptance

Dino automatically accepts new OMEMO keys from your own other devices and your chat partners by default. This default behaviour leads to the fact that the admin of the XMPP server could inject own public OMEMO keys without user verification, which enables the owner of the associated private OMEMO keys to decrypt your OMEMO secured conversation without being easily noticed.

To prevent this, two actions are required, the second consists of several steps and must be taken for each new chat partner.

- First, the automatic acceptance of new keys from your own other devices must be deactivated. Configure this in the account settings of your own accounts.
- Second, the automatic acceptance of new keys from your chat partners must be deactivated. Configure this in the contact details of every chat partner. Be aware that in the case of group chats, the entire communication can be decrypted unnoticed if even one partner does not actively deactivate automatic acceptance of new OMEMO keys.

Always confirm new keys from your chat partner before accepting them manually

feat(dino#Dino does not use encryption by default): Dino does not use encryption by default

You have to initially enable encryption in the conversation window by clicking the lock-symbol and choose OMEMO. Future messages and file transfers to this contact will be encrypted with OMEMO automatically.

- Every chat partner has to enable encryption separately.
- If only one of two chat partner has activated OMEMO, only this part of the communication will be encrypted. The same applies with file transfers.
- If you get a message "This contact does not support OMEMO" make sure that your chatpartner has accepted the request to add him to your contact list and you accepted vice versa

feat(dino#Install in Tails): Install in Tails

If you have more detailed follow [this article](https://t-hinrichs.net/DinoTails/DinoTails_recent.html) at the same time as you read this one. That one is more outdated but more detailed.

- Boot a clean Tails
- Create and configure the Persistent Storage
- Restart Tails and open the Persistent Storage

- Configure the persistence of the directory:
    ```bash
    echo -e '/home/amnesia/.local/share/dino source=dino' | sudo tee -a /live/persistence/TailsData_unlocked/persistence.conf > /dev/null
    ```
- Restart Tails

- Install the application:
    ```bash
    sudo apt-get update
    sudo apt-get install dino-im
    ```
- Configure the `dino-im` alias to use `torsocks`

    ```bash
    sudo echo 'alias dino="torsocks dino-im &> /dev/null &"' >> /live/persistence/TailsData_unlocked/dotfiles/.bashrc
    echo 'alias dino="torsocks dino-im &> /dev/null &"' >> ~/.bashrc
    ```

fix(gadgetbridge#installation): Installation on GrapheneOS

On [GrapheneOS](grapheneos.md) you may need to [enable the restricted permissions](https://support.google.com/android/answer/12623953?hl=en)

feat(galego): Introduce galego

O [galego](https://gl.wikipedia.org/wiki/Lingua_galega) é unha lingua
indoeuropea que pertence á póla de linguas románicas. É a lingua propia de
Galiza, onde é falada por uns 2.4 millóns de galegas. Á parte de en Galiza,
a lingua falase tamén en territórios limítrofes con esta comunidade, ainda que
sen estatuto de oficialidade, asi como pola diáspora galega que emigrou a outras
partes do estado español, América latina, os Estados Unidos, Suíza e outros
países do Europa.

feat(galego#Te e che. Trucos para saber diferencialos): Te e che. Trucos para saber diferencialos

En galego temos dúas formas para o pronome átono da segunda persoa do singular: te e che.

O pronome te ten a función de complemento directo (CD) e o pronome che de complemento indirecto (CI).

Cando se utiliza o pronome te?

O pronome te utilízase cando ten a función de CD, propio dos verbos transitivos, xa que alude ao ser ou ao obxecto sobre o que recae a acción verbal.

Se convertemos a oración en pasiva, o CD pasa a ser o suxeito. Por exemplo:

Vinte na cafetería / Ti fuches visto por min na cafetería.

Cando se utiliza o pronome che?

O pronome che utilízase cando ten a función de CI, xa que indica o destinatario da acción expresada polo verbo. Por exemplo:

Díxenche a verdade.

Compreiche unhas lambonadas.

Truco para saber diferencialos

Un truco moi rápido para diferenciarmos os pronomes te e che é substituír eses pronomes de segunda persoa polos de terceira.

Se podemos cambiar ese pronome por o/lo/no ou a/la/na, quere dicir que o pronome vai ser de CD. Polo tanto, temos que poñer te.

Saudeite onte pola rúa / Saudeino onte pola rúa.

Chameite por teléfono / Chameina por teléfono.

Se podemos substituílo por un lle, significa que é un pronome de CI e que debemos utilizar o che.

Lévoche mañá os apuntamentos / Lévolle mañá os apuntamentos.

Collinche as entradas do concerto / Collinlle as entradas do concerto.

feat(galego#Uso de asemade): Uso de asemade

Asemade pode utilizarse como adverbio cando ten o significado de ‘ao mesmo tempo’ ou ‘simultaneamente’. Ainda que normalmente úsase no registro culto, non utilizalo na fala.

- Non se pode comer e falar asemade.
- Non podes facer os deberes e ver a televisión asemade, pois non te concentras.

Tamén se pode utilizar como conxunción co significado de ‘tan pronto como’.

- Foi o primeiro que vimos asemade entramos.
- Recoñecino asemade o vin.

É incorrecto empregar asemade como sinónimo de tamén, ademais ou igualmente.

feat(galego#referencias): Referencias e libros de gramática

Referencias:

* [Dicionario](https://academia.gal/dicionario)
* [Traductor](https://tradutor.dacoruna.gal/fron-trad/index_es.html)
* [Juego Pensatermos](https://pensatermos.amesa.gal)
* [Conxugador de verbos](http://cotovia.org/proxecto/conxugador/index.html)
* [Celga-1 materiais](https://www.lingua.gal/o-galego/aprendelo/celga-1/materiais-de-clase)
* [Recursos para aprender o galego](https://www.lingua.gal/recursos/para-aprender-o-galego)

* [Recompilación de grupos de música en galego](https://orgullogalego.gal/musica-en-galego/)
* [Conversas do fenómeno das persoas neofalantes e o futuro do idioma](https://www.youtube.com/watch?app=desktop&v=7al60UuHlU8&feature=youtu.be)

Libros gramática:

* [Gramática da Lingua Galega de Xosé Feixó Cid](https://www.xerais.gal/libro.php?id=927711)
* [Como falar e escribir en galego con corrección e fluidez de Carlos Callón](https://www.xerais.gal/libro.php?id=3337926)
* [Manual de conxugación verbal da lingua galega de Avelino Hermida](https://editorialgalaxia.gal/produto/manual-de-conxugacion-verbal-da-lingua-galega/)
* [Dicionario Galaxia de usos e dificultades da lingua galega de Benigno
    Fernández Salgado](https://editorialgalaxia.gal/produto/dicionario-galaxia-de-usos-e-dificultades-da-lingua-galega/)

fix(git): Search for alternatives to git-sweep

The tool is [no longer maintained](arc90/git-sweep#45) but there is still no good alternative. I've found some but are either not popular and/or not maintained:

- [gitsweeper](https://github.com/petems/gitsweeper)
- [git-removed-brances](https://github.com/nemisj/git-removed-branches)
- [git-sweep rewrite in go](https://github.com/gottwald/git-sweep)

fix(gitea): Update disable regular login with oauth

The last `signin_inner.tmpl` failed with the latest version. I've
uploaded the new working one.

feat(grocy_management#Doing the inventory review): Doing the inventory review

I haven't found a way to make the grocy inventory match the reality because for me it's hard to register when I consume a product. Even more if other people also use them. Therefore I use grocy only to know what to buy without thinking about it. For that use case the inventory needs to meet reality only before doing the groceries. I usually do a big shopping of non-perishable goods at the supermarket once each two or three months, and a weekly shopping of the rest.

Tracking the goods that are bought each week makes no sense as those are things that are clearly seen and are very variable depending on the season. Once I've automated the ingestion and consumption of products it will, but so far it would mean investing more time than the benefit it gives.

This doesn't apply to the big shopping, as this one is done infrequently, so we need a better planning.

To do the inventory review I use a tablet and the [android app](https://github.com/patzly/grocy-android).

- [ ] Open the stock overview and iterate through the locations to:
  - [ ] Make sure that the number of products match the reality
    - [ ] Iterate over the list of products checking the quantity
    - [ ] Look at the location to see if there are missing products in the inventory
  - [ ] Adjust the product properties (default location, minimum amount)
- [ ] Check the resulting shopping list and adjust the minimum values.
- [ ] Check the list of missing products to adjust the minimum values. I have a notepad in the fridge where I write the things I miss.

feat(life_review#Thoughts on the reviews themselves): Thoughts on the reviews themselves

- Keep It Simple: It's important for the process to be light enough that you want to actually do it, so you see it as a help instead of a burden. It's always better to do a small and quick review rather than nothing at all. At the start of the review analyze yourself to assess how much energy do you have and decide which steps of the review you want to do.

- Review approaches: In the past I used the [life logging](life_logging.md) tools to analyze the past in order to understand what I achieved and take it as a base to learn from my mistakes. It was useful when I needed the endorphines boost of seeing all the progress done. Once I assumed that progress speed and understood that we always do the best we can given how we are, I started to feel that the review process was too cumbersome and that it was holding me into the past.

  Nowadays I try not to look back but forward, analyze the present: how I feel, how's the environment around me, and how can I tweak both to fulfill my life goals. This approach leads to less reviewing of achievements and logs and more introspection, thinking and imagining. Which although may be slower to correct mistakes of the past, will surely make you live closer to the utopy.

  The reviews below then follow that second approach.

- Personal alive reviews: Reviews have to reflect ourselves, and we change continuously, so take for granted that your review is going to change.

  I've gone for full blown reviews of locking myself up for a week to not doing reviews for months.

  This article represent the guidelines I follow to do my life review. It may
  seem a lot to you or may be very simple. Please take it as a base or maybe to
  get some ideas and then create your own that fits your needs.

feat(life_review#Month review tools): Update the Month review process

feat(life_review#When to do the trimester reviews): When to do the trimester reviews

As with [moth reviews](life_review.md#month-review), it's interesting to do analysis at representative moments. It gives it an emotional weight. You can for example use the solstices or my personal version of the solstices:

- Spring analysis (1st of March): For me the spring is the real start of the year, it's when life explodes after the stillness of the winter. The sun starts to set later enough so that you have light in the afternoons, the climate gets warmer thus inviting you to be more outside, the nature is blooming new leaves and flowers. It is then a moment to build new projects and set the current year on track.

- Summer analysis (1st of June): I hate heat, so summer is a moment of retreat. Everyone temporarily stop their lives, we go on holidays and all social projects slow their pace. Even the news have even less interesting things to report. It's so hot outside that some of us seek the cold refuge of home or remote holiday places. Days are long and people love to hang out till late, so usually you wake up later, thus having less time to actually do stuff. Even in the moments when you are alone the heat drains your energy to be productive. It is then a moment to relax and gather forces for the next trimester. It's also perfect to develop *easy* and *chill* personal projects that have been forgotten in a drawer. Lower your expectations and just flow with what your body asks you.

- Autumn analysis (1st of September): September it's another key moment for many people. We have it hardcoded in our life since we were children as it was the start of school. People feel energized after the summer holidays and are eager to get back to their lives and stopped projects. You're already 6 months into the year, so it's a good moment to review your year plan and decide how you want to invest your energy reserves.

- Winter analysis (1st of December): December is the cue that the year is coming to an end. The days grow shorter and colder, they basically invite you to enjoy a cup of tea under a blanket. It is then a good time to get into your cave and do an introspection analysis on the whole year and prepare the ground for the coming year. Some of the goals of this season are:
  - Think everything you need to guarantee a good, solid and powerful spring start.
  - Do the year review to adjust your principles.

The year is then divided in two sets of an expansion trimester and a retreat one. We can use this information to adjust our life plan accordingly. In the expansion trimester we could invest more energies in the planning, and in the retreat ones we can do more throughout reviews.

feat(life_review#The principle documents): The principle documents

Principle documents for me are [orgmode](orgmode.md) documents where I think about the principle itself. It acts both as a way of understanding it and evolving my idea around it, and to build the roadmap to materialize the principle's path.

Without ever having created one I feel that it makes sense to make the reflection part public in the blue book, while I keep for myself the private one. This may also change between principles.

feat(life_review#The life path document): The life path document

The life path document is an [orgmode](orgmode.md) document where I think about what I want to do with my life and how. It's the highest level of abstraction of the life management system.

The structure so far is as follows:

```orgmode
* Life path
** {year}
*** Principles of {season} {year}
    {Notes on the season}
    - Principle 1
    - Principle 2
    ...

**** Objectives of {month} {year}
     - [-] Objective 1
       - [X] SubObjective 1
       - [ ] SubObjective 2
     - [ ] Objective 2
     - [ ] ...
```

Where the principles are usually links to principle documents and the objectives links to tasks.

feat(life_review#Trimester prepare): Trimester prepare

The trimester review requires an analysis that doesn't fill in a day session. It requires slow thinking over some time. So I'm creating a task 10 days before the actual review to start thinking about the next trimester. Whether it's ideas, plans, desires, objectives, or principles.

Is useful for that document to be available wherever you go, so that in any spare time you can pop it up and continue with the train of thought.

Doing the reflection without seeing your life path prevents you from being tainted by it, thus representing the real you of right now.

On the day to actually do the review, follow the steps of the [Month review prepare](life_review.md#month-prepare) adjusting them to the trimester case.

feat(syncthing#Change the path of a folder): Change the path of a folder

- Shutdown Syncthing
- Edit the config file (`~/.config/syncthing/config.xml`)
- Search and replace the path
- Start again syncthing

feat(linux_snippets#Makefile use bash instead of sh): Makefile use bash instead of sh

The program used as the shell is taken from the variable `SHELL`.  If
this variable is not set in your makefile, the program `/bin/sh` is
used as the shell.

So put `SHELL := /bin/bash` at the top of your makefile, and you should be good to go.

feat(linux_snippets#Recover the message of a commit if the command failed): Recover the message of a commit if the command failed

`git commit` can fail for reasons such as `gpg.commitsign = true` && `gpg` fails, or when running a pre-commit. Retrying the command opens a blank editor and the message seems to be lost.

The message is saved though in `.git/COMMIT_EDITMSG`, so you can:

```bash
git commit -m "$(cat .git/COMMIT_EDITMSG)"
```

Or in general (suitable for an alias for example):

```bash
git commit -m "$(cat "$(git rev-parse --git-dir)/COMMIT_EDITMSG)")"
```

feat(lua#Inspect contents of Lua table in Neovim): Inspect contents of Lua table in Neovim

When using Lua inside of Neovim you may need to view the contents of Lua tables, which are a first class data structure in Lua world. Tables in Lua can represent ordinary arrays, lists, symbol tables, sets, records, graphs, trees, etc.

If you try to just print a table directly, you will get the reference address for that table instead of the content, which is not very useful for most debugging purposes:

```lua
:lua print(vim.api.nvim_get_mode())
" table: 0x7f5b93e5ff88
```

To solve this, Neovim provides the `vim.inspect` function as part of its API. It serializes the content of any Lua object into a human readable string.

For example you can get information about the current mode like so:

```lua
:lua print(vim.inspect(vim.api.nvim_get_mode()))
" {  blocking = false,  mode = "n"}
```

feat(ombi#Set default quality of request per user): Set default quality of request per user

Sometimes one specific user continuously asks for a better quality of the content. If you go into the user configuration (as admin) you can set the default quality profiles for that user.

feat(orgmode#Start working on a task dates): Start working on a task dates

`SCHEDULED` defines when you are plan to start working on that task.

The headline is listed under the given date. In addition, a reminder that the scheduled date has passed is present in the compilation for today, until the entry is marked as done or [disabled](#how-to-deal-with-overdue-SCHEDULED-and-DEADLINE-tasks).

```org
*** TODO Call Trillian for a date on New Years Eve.
    SCHEDULED: <2004-12-25 Sat>
```

Although is not a good idea (as it promotes the can pushing through the street), if you want to delay the display of this task in the agenda, use `SCHEDULED: <2004-12-25 Sat -2d>` the task is still scheduled on the 25th but will appear two days later. In case the task contains a repeater, the delay is considered to affect all occurrences; if you want the delay to only affect the first scheduled occurrence of the task, use `--2d` instead.

Scheduling an item in Org mode should not be understood in the same way that we understand scheduling a meeting. Setting a date for a meeting is just [a simple appointment](#appointments), you should mark this entry with a simple plain timestamp, to get this item shown on the date where it applies. This is a frequent misunderstanding by Org users. In Org mode, scheduling means setting a date when you want to start working on an action item.

You can set it with `<leader>s` (Default: `<leader>ois`)

feat(orgmode#Deadlines): Deadlines

`DEADLINE` are like [appointments](#appointments) in the sense that it defines when the task is supposed to be finished on. On the deadline date, the task is listed in the agenda. The difference with appointments is that you also see the task in your agenda if it is overdue and you can set a warning about the approaching deadline, starting `org_deadline_warning_days` before the due date (14 by default). It's useful then to set `DEADLINE` for those tasks that you don't want to miss that the deadline is over.

An example:

```org
* TODO Do this
DEADLINE: <2023-02-24 Fri>
```

You can set it with `<leader>d` (Default: `<leader>oid`).

If you need a different warning period for a special task, you can specify it. For example setting a warning period of 5 days `DEADLINE: <2004-02-29 Sun -5d>`.

If you're as me, you may want to remove the warning feature of `DEADLINES` to be able to keep your agenda clean. Most of times you are able to finish the task in the day, and for those that you can't specify a `SCHEDULED` date. To do so set the default number of days to `0`.

```lua
require('orgmode').setup({
  org_deadline_warning_days = 0,
})
```

Using too many tasks with a `DEADLINE` will clutter your agenda. Use it only for the actions that you need to have a reminder, instead try to using [appointment](#appointments) dates instead. The problem of using appointments is that once the date is over you don't get a reminder in the agenda that it's overdue, if you need this, use `DEADLINE` instead.

feat(orgmode#How to deal with overdue SCHEDULED and DEADLINE tasks.): How to deal with overdue SCHEDULED and DEADLINE tasks.
If it's a recurring task you may want to keep the line for future iterations. That doesn't mean that it has to show in your agenda. If you have it already tracked you may want to hide it. One way I'm managing it is by deactivating the date (transforming the `<>` into `[]`) and adding a special state (`RDEACTIVATED`) so I don't mark the task as done by error. For example if we have:

```orgmode
** RDEACTIVATED Check the batteries in the smoke detectors
   SCHEDULED: [2005-11-01 Tue .+1m]
   Marking this DONE shifts the date to one month after today.
```

Once the task is ready to be marked as done you need to change the `[]` to `<>` and then you can mark it as `DONE`.

feat(orgmode#How to deal with recurring tasks that have checklists): How to deal with recurring tasks that have checklists

Some recurring tasks may have checklists. For example:

```orgmode
* TODO Clean the inbox
  SCHEDULED: <2024-01-04 ++1w>
  - [x] Clean email
  - [x] Clean physical inbox
  - [ ] Clean computer inbox
  - [ ] Clean mobile inbox
```

For those tasks that you want to always check before closing you can add a `(CHECK)` at the end of the title. The reason is because each time you mark a recurrent task as done it switches back the state to `TODO`. For example, as of right now nvim-orgmode doesn't support the recurrence type of "the first wednesday of the month". As a workaround you can do:

```orgmode
* TODO Do X the first thursday of the month (CHECK)
  DEADLINE: <2024-01-04 ++1m>

  - [ ] Step 1
  - [ ] Step 2
  - [ ] Step ...

  - [ ] Adjust the date to match the first thursday of the month
```

feat(orgmode): Gather all the archive files under a directory

If you [don't want to have dangling org_archive files](nvim-orgmode/orgmode#628) you can create an `archive` directory somewhere and then set:

```lua
local org = require('orgmode').setup({
  org_archive_location = "~/orgmode/archive/" .. "%s_archive",
)}
```

feat(orgmode#Use archiving to clean long checklists): Use archiving to clean long checklists

When you have big tasks that have nested checklists, when you finish the day working on the task you may want to clean the checklist without loosing what you've done, for example for reporting purposes.

In those cases what I do is archive the task, and then undo the archiving. That way you have a copy of the state of the task in your archive with a defined date. Then you can safely remove the done checklist items.

feat(python#Exceptions): Table of exceptions

The table below shows built-in exceptions that are usually raised in Python:

| Exception | 	Description |
| --- | --- |
| ArithmeticError | 	Raised when an error occurs in numeric calculations |
| AssertionError | 	Raised when an assert statement fails |
| AttributeError | 	Raised when attribute reference or assignment fails |
| Exception | 	Base class for all exceptions |
| EOFError | 	Raised when the input() method hits an "end of file" condition (EOF) |
| FloatingPointError | 	Raised when a floating point calculation fails |
| GeneratorExit | 	Raised when a generator is closed (with the close() method) |
| ImportError | 	Raised when an imported module does not exist |
| IndentationError | 	Raised when indentation is not correct |
| IndexError | 	Raised when an index of a sequence does not exist |
| KeyError | 	Raised when a key does not exist in a dictionary |
| KeyboardInterrupt | 	Raised when the user presses Ctrl+c, Ctrl+z or Delete |
| LookupError | 	Raised when errors raised cant be found |
| MemoryError | 	Raised when a program runs out of memory |
| NameError | 	Raised when a variable does not exist |
| NotImplementedError | 	Raised when an abstract method requires an inherited class to override the method |
| OSError | 	Raised when a system related operation causes an error |
| OverflowError | 	Raised when the result of a numeric calculation is too large |
| ReferenceError | 	Raised when a weak reference object does not exist |
| RuntimeError | 	Raised when an error occurs that do not belong to any specific exceptions |
| StopIteration | 	Raised when the next() method of an iterator has no further values |
| SyntaxError | 	Raised when a syntax error occurs |
| TabError | 	Raised when indentation consists of tabs or spaces |
| SystemError | 	Raised when a system error occurs |
| SystemExit | 	Raised when the sys.exit() function is called |
| TypeError | 	Raised when two different types are combined |
| UnboundLocalError | 	Raised when a local variable is referenced before assignment |
| UnicodeError | 	Raised when a unicode problem occurs |
| UnicodeEncodeError | 	Raised when a unicode encoding problem occurs |
| UnicodeDecodeError | 	Raised when a unicode decoding problem occurs |
| UnicodeTranslateError | 	Raised when a unicode translation problem occurs |
| ValueError | 	Raised when there is a wrong value in a specified data type |
| ZeroDivisionError | 	Raised when the second operator in a division is zero |

feat(rich#Configure the logging handler): Configure the logging handler

Rich supplies a logging handler which will format and colorize text written by Python’s logging module.

Here’s an example of how to set up a rich logger:

```python
import logging
from rich.logging import RichHandler

FORMAT = "%(message)s"
logging.basicConfig(
    level="NOTSET", format=FORMAT, datefmt="[%X]", handlers=[RichHandler()]
)

log = logging.getLogger("rich")
log.info("Hello, World!")
```

If you want to use different levels with the verbose use:

```python
def load_logger(verbose: bool = False) -> None:
    """Configure the Logging logger.

    Args:
        verbose: Set the logging level to Debug.
    """

    if verbose:
        level = logging.DEBUG
    else:
        level = logging.INFO
    logging.basicConfig(
        format="%(message)s",
        level=level,
        handlers=[RichHandler()],
    )
```

feat(shellcheck#SC1090: Can't follow non-constant source. Use a directive to specify location): SC1090: Can't follow non-constant source. Use a directive to specify location

Problematic code:

```bash
. "${util_path}"
```

Correct code:

```bash
. "${util_path}"
```

Rationale:

ShellCheck is not able to include sourced files from paths that are determined at runtime. The file will not be read, potentially resulting in warnings about unassigned variables and similar.

Use a Directive to point shellcheck to a fixed location it can read instead.

Exceptions:

If you don't care that ShellCheck is unable to account for the file, specify `# shellcheck source=/dev/null`.

feat(tails#pass): Configure pass

To configure `pass` you need to first [configure the persistent storage](#configure-the-persistent-storage) and then:

```bash
echo -e '/home/amnesia/.password-store source=pass' | sudo tee -a /live/persistence/TailsData_unlocked/persistence.conf > /dev/null
```

Restart tails and then initialize the `pass` store with `pass init your-gpg-id`.

feat(tails#Configure the persistent storage): Configure the persistent storage

When the Dotfiles feature is turned on:

- All the files in the `/live/persistence/TailsData_unlocked/dotfiles` folder are linked in the Home folder using Linux symbolic links.

- All the files in subfolders of `/live/persistence/TailsData_unlocked/dotfiles` are also linked in the corresponding subfolder of the Home folder using Linux symbolic links.

- A shortcut is provided in the left pane of the Files browser and in the Places menu in the top navigation bar to access the `/live/persistence/TailsData_unlocked/dotfiles` folder.

For example, having the following files in `/live/persistence/TailsData_unlocked/dotfiles`:

```
/live/persistence/TailsData_unlocked/dotfiles
├── file_a
├── folder
│   ├── file_b
│   └── subfolder
│       └── file_c
└── emptyfolder
```

Produces the following result in `/home/amnesia`:

```
/home/amnesia
├── file_a → /live/persistence/TailsData_unlocked/dotfiles/file_a
└── folder
    ├── file_b → /live/persistence/TailsData_unlocked/dotfiles/folder/file_b
    └── subfolder
        └── file_c → /live/persistence/TailsData_unlocked/dotfiles/folder/subfolder/file_c
```

feat(tenacity#Full example of retry): Full example of retry

```python
from tenacity import retry
from tenacity.stop import stop_after_attempt
from tenacity.wait import wait_exponential

@Retry(
    stop=stop_after_attempt(5), wait=wait_exponential(multiplier=3, min=1, max=300)
)
def function():
    pass
```

feat(typer#Arguments with help): Arguments with help

```python
import typer
from typing_extensions import Annotated

def main(name: Annotated[str, typer.Argument(help="The name of the user to greet")]):
    print(f"Hello {name}")
```

feat(typer#Create a verbose argument): Create a verbose argument
A simple `--verbose` and `-v` flag can be defined as:

```python
import typer

def main(
    verbose: Annotated[bool, typer.Option("--verbose", "-v")] = False,
):
    print(f"Verbose level is {verbose}")

if __name__ == "__main__":
    typer.run(main)
```

feat(typer#Add a --help and -h command): Add a --help and -h command

`typer` by default gives the `--help` command. If you want `-h` to work too add:

```python
import typer

app = typer.Typer(context_settings={"help_option_names": ["-h", "--help"]})

@app.command()
def main(name: str):
    print(f"Hello {name}")

if __name__ == "__main__":
    app()
```

feat(vim#Neovim plugin debug): Neovim plugin debug

If you use [packer](#packer) your plugins will be installed in `~/.local/share/nvim/site/pack/packer/start/`. You can manually edit those files to develop new feature or fix issues on the plugins.

To debug a plugin read it's source code and try to load in a lua shell the relevant code. If you are in a vim window you can run lua code with `:lua your code here`, for example `:lua Files = require('orgmode.parser.files')`, you can then do stuff with the `Files` object.

Remember that if you need to print the contents of a table [you can use `vim.inspect`](lua.md#inspect-contents-of-Lua-table-in-Neovim).

Another useful tip for Lua newbies (like me) can be to use `print` statements to debug the state of the variables. If it doesn't show up in vim use `error` instead, although that will break the execution with an error.

feat(vim#Get the name of the file shown): Get the name of the file shown

`:f` (`:file`) will do same as `<C-G>`. `:f!` will give a untruncated version, if applicable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants