{"id":18552904,"url":"https://github.com/oderwat/bearnanny","last_synced_at":"2025-08-01T23:42:20.484Z","repository":{"id":141012939,"uuid":"101108531","full_name":"oderwat/BearNanny","owner":"oderwat","description":"An experimental \"live processor\" for Bear notes with special markers","archived":false,"fork":false,"pushed_at":"2017-10-04T22:01:39.000Z","size":20352,"stargazers_count":19,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-07-24T15:30:05.792Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oderwat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-22T21:22:32.000Z","updated_at":"2024-08-24T23:41:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"89a9d04c-c941-4347-b27f-e9dd7ee6cbc9","html_url":"https://github.com/oderwat/BearNanny","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/oderwat/BearNanny","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oderwat%2FBearNanny","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oderwat%2FBearNanny/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oderwat%2FBearNanny/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oderwat%2FBearNanny/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oderwat","download_url":"https://codeload.github.com/oderwat/BearNanny/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oderwat%2FBearNanny/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268314657,"owners_count":24231031,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T21:15:29.174Z","updated_at":"2025-08-01T23:42:20.462Z","avatar_url":"https://github.com/oderwat.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BearNanny (experimental)\n\n[Bear](http://www.bear-writer.com/) is my most favorite note-taking application. This experimental shell application extends what you can do by watching the Bear notes and act on their contents.\n\n![Demo 1](assets/demo1.gif)\n\n## Using it:\n\nStart BearNanny either by running `swift run` or build the executable with `swift build -c release -Xswiftc -static-stdlib` and maybe `strip .build/release/BearNanny`.\n\n\u003e I added a (hopefully) working version in the `bin/` folder of the project!\n\u003e\n\u003e*Please note that this binary won't be updated if you make changes and compile it yourself!*\n\nWith that running open up Bear and write a note with the following content:\n\n    # BearNanny Test\n\n    ```swift\n    let a = 7\n    let b = 8\n    print(a * b)\u003c\u003c\u003c\u003c\n    ```\n    ```output\n    ```\n    ---\n    #BearNanny\n\n\nAfter a short time BearNanny should output some information to the console (in verbose mode) and the output part of the note should update to:\n\n    ```output 1fquuqd4jqb30\n    56\n    ```\n\nThe characters after the word output are a checksum of the code which helps avoiding recalculation. It also does not update the note if the output is the same as before like when editing comments.\n\nYou can have multiple notes and sections which contain such swift code / output sections. BearNanny will check every other second for changes (and runs endlessly).\n\nUsing a run trigger (default `\u003c\u003c\u003c\u003c`) for re-computing the output has two reasons:\n\n1. Before using the trigger, BearNanny was running the code much to often. Nice for the initial proof of concept but not really useful. Now you can trigger running the code when your changes are done.\n2. Bear currently still loses focus and cursor position when a note gets updated from external. So I figured out a very hacky trick to work around this: I figure out the line and column of the trigger in the note. After running the code and updating the note with the new output I create and run a little Apple Script to send keystrokes to the Bear Application which moves the cursor (hopefully) to the location the trigger was found.\n\nYou can also define a trigger for code block formatting (currently only for Swift code utilising `swiftformat`) which can be used to re-format a code block with a simple trigger. See below configuration for an example.\n\n#### BearNanny Config\n\nAs the code trigger may not fit for your use case you can change it by creating a code block with the following content:\n\n    ```BearNanny\n    RunTrigger: \u003c\u003c\u003c\u003c\n    FormatTrigger: \u003e\u003e\u003e\u003e\n    FormatOnRun: true\n    FormatSwift: swiftformat --indent 2\n    ```\n\n*Notice: All occurences of the triggers get erased in the code block when found!*\n\n### Meta blocks\n\nYou can now define a meta block which lets you do some more cool stuff:\n\nHere some examples:\n\n#### Saving a code block to the filesystem (and chmod it)\n\n    ```meta\n    saveas: ~/bin/myscript\n    chmod: 0777\n    ```\n    ```shell\n    #!/bin/bash\n    echo \"I was created in Bear!\n    ```\n\nSaving happens automatically every time the code gets changed. There is no trigger needed!\n\n*Take care as it will not ask you if the file it saves already exists!*\n\n#### Running a shell command on a code block\n\n    ```meta\n    run: sort\n    ```\n    ```\n    this\n    is\n    an\n    unsorted\n    list\n    ```\n    ```output 1n1oz33f4bxj0\n    an\n    is\n    list\n    this\n    unsorted\n    ```\n\n#### Running a MySQL Query on a local database\n\nThis uses the recently added feature that you can use `\u003c` as last option to a run command which then pipes the code block to the running command as standard input.\n\n    ```meta\n    run: mysql -sr -h localhost -u test test \u003c\n    ```\n    ```sql\n    SELECT \"SQL Example with some Text!\\n\\nUserlist:\";\n    SELECT * FROM users;\n    SELECT \"\";  # creates an empty line\n    SELECT CONCAT(\"Total users: \",COUNT(*)) FROM users;\n    SELECT CONCAT(\"Total age: \",SUM(age)) FROM users;\n    ```\n    ```output\n    SQL Example with some Text!\n\n    Userlist:\n    bob\t35\t2017-09-18 12:51:20\n    joe\t16\t2017-09-18 12:51:29\n    max\t23\t2017-09-18 12:51:43\n\n    Total users: 3\n    Total age: 74\n    ```\n\n*P.S.: The `-r` option is needed to emit a real linefeed instead of `\\n`*\n\n#### PHP (and Python) support\n\n    ```php\n    echo date('Y-m-d H:i:s')\n    ```\n    ```output\n    ```\n\n#### Complex Usage\n\nYou can combine \"run\" and \"saveas\" to store the code you run at the same time. You can even use some \"saveas\" blocks to transfer data from the note to files which then are used by a \"run\" code block.\n\n### Synced Content\n\nIt will also work on connected devices if you have BearNanny running on one of them :)\n\n## Here some notes about compiling and running it!\n\n### Background and my procedure for creating the package (for reference):\n\nI use XCode 9 beta 6 and [swiftenv](https://swiftenv.fuller.li/en/latest/) (`brew install swiftenv`) for compilation with Swift 4. I just started learning Swift and don't want to force me into learning old stuff which is being outdated soon anyway.\n\nTo build this project one needs the Swift 4 version of the SQLite Package. I shortly describe the steps I took to make this work:\n\nSetting up the package was done like this and is already done if you checked out this repository. I list it mostly for reference:\n\n```bash\nmkdir BearNanny\ncd BearNanny\nswiftenv local 4.0 # using Swift 4 here\nswift package init --type executable\n```\n\nEditing `Package.swift` to contain :\n\n```swift\n// swift-tools-version:4.0\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"BearNanny\",\n    dependencies: [\n        // Make sure to use the swift-4 branch (by `swift package edit SQLite` and \"git co swift-4\")\n        .package(url: \"https://github.com/stephencelis/SQLite.swift\", from: \"0.11.0\"),\n    ],\n    targets: [\n        // Targets are the basic building blocks of a package. A target can define a module or a test suite.\n        // Targets can depend on other targets in this package, and on products in packages which this package depends on.\n        .target(\n            name: \"BearNanny\",\n            dependencies: [\"SQLite\"]),\n    ]\n)\n```\n\n### What you need to do for successful compilation (needed):\n\nNow marking the SQLite Package as editable and checking out the Swift 4 version and updating the package.\n\n```\nswift package edit SQLite\ncd Packages/SQLite/\ngit checkout swift-4\ncd -\necho \"Package.resolved\" \u003e\u003e .gitignore\nswift package update\n```\n\n### Editing with XCode 9 or AppCode 2017.2 (optional):\n\nCreating the XCode Project (just because I use XCode 9 and AppCode 2017.2 for editing and debugging the files).\n\n```\nswift package generate-xcodeproj\n```\n\nTo be able to compile it with XCode 9 (or AppCode) there needs to be `Enable Modules (C and Objective-C)` set to `Yes` for the target `SQLiteObjc`.\n\nThis seems not to matter if compiling with `swift build` or just `swift run` the project.\n\n*I know the SIGINT code is bogus! But it is better than nothing*\n\n### Remember: This is an experimental application to explore the possibilities and one of my very first Swift programming experiences. Have fun!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foderwat%2Fbearnanny","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foderwat%2Fbearnanny","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foderwat%2Fbearnanny/lists"}