├── .copier-answers.yml
├── .github
└── workflows
│ ├── binder-on-pr.yml
│ ├── build.yml
│ ├── check-release.yml
│ ├── enforce-label.yml
│ ├── prep-release.yml
│ └── publish-release.yml
├── .gitignore
├── .prettierignore
├── .yarnrc.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── RELEASE.md
├── binder
├── apt.txt
├── environment.yml
├── postBuild
└── tutorial.ipynb
├── doc
└── settings.png
├── install.json
├── jupyter-config
└── server-config
│ └── jupyterlab_quickopen.json
├── jupyterlab_quickopen
├── __init__.py
└── handler.py
├── package.json
├── pyproject.toml
├── schema
└── plugin.json
├── setup.py
├── src
├── handler.ts
└── index.ts
├── style
├── base.css
├── index.css
└── index.js
├── tsconfig.json
└── yarn.lock
/.copier-answers.yml:
--------------------------------------------------------------------------------
1 | # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
2 | _commit: v4.3.5
3 | _src_path: https://github.com/jupyterlab/extension-template
4 | author_email: parente@gmail.com
5 | author_name: Peter Parente
6 | has_binder: true
7 | has_settings: true
8 | kind: server
9 | labextension_name: 'jupyterlab-quickopen'
10 | project_short_description: Quickly open a file in JupyterLab by part of its name
11 | python_name: jupyterlab_quickopen
12 | repository: https://github.com/jupyterlab-contrib/jupyterlab-quickopen.git
13 | test: false
14 |
15 |
--------------------------------------------------------------------------------
/.github/workflows/binder-on-pr.yml:
--------------------------------------------------------------------------------
1 | name: Binder Badge
2 | on:
3 | pull_request_target:
4 | types: [opened]
5 |
6 | jobs:
7 | binder:
8 | runs-on: ubuntu-latest
9 | permissions:
10 | pull-requests: write
11 | steps:
12 | - uses: jupyterlab/maintainer-tools/.github/actions/binder-link@v1
13 | with:
14 | github_token: ${{ secrets.GITHUB_TOKEN }}
15 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | branches: main
6 | pull_request:
7 | branches: '*'
8 |
9 | concurrency:
10 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
11 | cancel-in-progress: true
12 |
13 | jobs:
14 | build:
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - name: Checkout
19 | uses: actions/checkout@v4
20 |
21 | - name: Base Setup
22 | uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
23 |
24 | - name: Install dependencies
25 | run: python -m pip install -U "jupyterlab>=4.0.0,<5"
26 |
27 | - name: Lint the extension
28 | run: |
29 | set -eux
30 | jlpm
31 | jlpm run lint:check
32 |
33 | - name: Build the extension
34 | run: |
35 | set -eux
36 | python -m pip install . -vv
37 |
38 | jupyter server extension list
39 | jupyter server extension list 2>&1 | grep -ie "jupyterlab_quickopen.*OK"
40 |
41 | jupyter labextension list
42 | jupyter labextension list 2>&1 | grep -ie "jupyterlab-quickopen.*OK"
43 | python -m jupyterlab.browser_check
44 |
45 | - name: Package the extension
46 | run: |
47 | set -eux
48 |
49 | pip install build
50 | python -m build
51 | pip uninstall -y "jupyterlab_quickopen" jupyterlab
52 |
53 | - name: Upload extension packages
54 | uses: actions/upload-artifact@v4
55 | with:
56 | name: extension-artifacts
57 | path: dist/jupyterlab_quickopen*
58 | if-no-files-found: error
59 |
60 | test_isolated:
61 | needs: build
62 | runs-on: ubuntu-latest
63 |
64 | steps:
65 | - name: Install Python
66 | uses: actions/setup-python@v5
67 | with:
68 | python-version: '3.9'
69 | architecture: 'x64'
70 | - uses: actions/download-artifact@v4
71 | with:
72 | name: extension-artifacts
73 | - name: Install and Test
74 | run: |
75 | set -eux
76 | # Remove NodeJS, twice to take care of system and locally installed node versions.
77 | sudo rm -rf $(which node)
78 | sudo rm -rf $(which node)
79 |
80 | pip install "jupyterlab>=4.0.0,<5" jupyterlab_quickopen*.whl
81 |
82 |
83 | jupyter server extension list
84 | jupyter server extension list 2>&1 | grep -ie "jupyterlab_quickopen.*OK"
85 |
86 | jupyter labextension list
87 | jupyter labextension list 2>&1 | grep -ie "jupyterlab-quickopen.*OK"
88 | python -m jupyterlab.browser_check --no-browser-test
89 |
90 |
91 | check_links:
92 | name: Check Links
93 | runs-on: ubuntu-latest
94 | timeout-minutes: 15
95 | steps:
96 | - uses: actions/checkout@v4
97 | - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
98 | - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1
99 | with:
100 | ignore_links: https://mybinder.org/*
101 |
--------------------------------------------------------------------------------
/.github/workflows/check-release.yml:
--------------------------------------------------------------------------------
1 | name: Check Release
2 | on:
3 | push:
4 | branches: ["main"]
5 | pull_request:
6 | branches: ["*"]
7 |
8 | concurrency:
9 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
10 | cancel-in-progress: true
11 |
12 | jobs:
13 | check_release:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - name: Checkout
17 | uses: actions/checkout@v4
18 | - name: Base Setup
19 | uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
20 | - name: Check Release
21 | uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2
22 | with:
23 | token: ${{ secrets.GITHUB_TOKEN }}
24 |
25 | - name: Upload Distributions
26 | uses: actions/upload-artifact@v4
27 | with:
28 | name: jupyterlab-quickopen-releaser-dist-${{ github.run_number }}
29 | path: .jupyter_releaser_checkout/dist
30 |
--------------------------------------------------------------------------------
/.github/workflows/enforce-label.yml:
--------------------------------------------------------------------------------
1 | name: Enforce PR label
2 |
3 | on:
4 | pull_request:
5 | types: [labeled, unlabeled, opened, edited, synchronize]
6 | jobs:
7 | enforce-label:
8 | runs-on: ubuntu-latest
9 | permissions:
10 | pull-requests: write
11 | steps:
12 | - name: enforce-triage-label
13 | uses: jupyterlab/maintainer-tools/.github/actions/enforce-label@v1
14 |
--------------------------------------------------------------------------------
/.github/workflows/prep-release.yml:
--------------------------------------------------------------------------------
1 | name: "Step 1: Prep Release"
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | version_spec:
6 | description: "New Version Specifier"
7 | default: "next"
8 | required: false
9 | branch:
10 | description: "The branch to target"
11 | required: false
12 | post_version_spec:
13 | description: "Post Version Specifier"
14 | required: false
15 | # silent:
16 | # description: "Set a placeholder in the changelog and don't publish the release."
17 | # required: false
18 | # type: boolean
19 | since:
20 | description: "Use PRs with activity since this date or git reference"
21 | required: false
22 | since_last_stable:
23 | description: "Use PRs with activity since the last stable git tag"
24 | required: false
25 | type: boolean
26 | jobs:
27 | prep_release:
28 | runs-on: ubuntu-latest
29 | permissions:
30 | contents: write
31 | steps:
32 | - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
33 |
34 | - name: Prep Release
35 | id: prep-release
36 | uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@v2
37 | with:
38 | token: ${{ secrets.GITHUB_TOKEN }}
39 | version_spec: ${{ github.event.inputs.version_spec }}
40 | # silent: ${{ github.event.inputs.silent }}
41 | post_version_spec: ${{ github.event.inputs.post_version_spec }}
42 | branch: ${{ github.event.inputs.branch }}
43 | since: ${{ github.event.inputs.since }}
44 | since_last_stable: ${{ github.event.inputs.since_last_stable }}
45 |
46 | - name: "** Next Step **"
47 | run: |
48 | echo "Optional): Review Draft Release: ${{ steps.prep-release.outputs.release_url }}"
49 |
--------------------------------------------------------------------------------
/.github/workflows/publish-release.yml:
--------------------------------------------------------------------------------
1 | name: "Step 2: Publish Release"
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | branch:
6 | description: "The target branch"
7 | required: false
8 | release_url:
9 | description: "The URL of the draft GitHub release"
10 | required: false
11 | steps_to_skip:
12 | description: "Comma separated list of steps to skip"
13 | required: false
14 |
15 | jobs:
16 | publish_release:
17 | runs-on: ubuntu-latest
18 | environment: release
19 | permissions:
20 | id-token: write
21 | steps:
22 | - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
23 |
24 | - uses: actions/create-github-app-token@v1
25 | id: app-token
26 | with:
27 | app-id: ${{ vars.APP_ID }}
28 | private-key: ${{ secrets.APP_PRIVATE_KEY }}
29 |
30 | - name: Populate Release
31 | id: populate-release
32 | uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@v2
33 | with:
34 | token: ${{ steps.app-token.outputs.token }}
35 | branch: ${{ github.event.inputs.branch }}
36 | release_url: ${{ github.event.inputs.release_url }}
37 | steps_to_skip: ${{ github.event.inputs.steps_to_skip }}
38 |
39 | - name: Finalize Release
40 | id: finalize-release
41 | env:
42 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
43 | uses: jupyter-server/jupyter_releaser/.github/actions/finalize-release@v2
44 | with:
45 | token: ${{ steps.app-token.outputs.token }}
46 | release_url: ${{ steps.populate-release.outputs.release_url }}
47 |
48 | - name: "** Next Step **"
49 | if: ${{ success() }}
50 | run: |
51 | echo "Verify the final release"
52 | echo ${{ steps.finalize-release.outputs.release_url }}
53 |
54 | - name: "** Failure Message **"
55 | if: ${{ failure() }}
56 | run: |
57 | echo "Failed to Publish the Draft Release Url:"
58 | echo ${{ steps.populate-release.outputs.release_url }}
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.bundle.*
2 | lib/
3 | node_modules/
4 | *.log
5 | .eslintcache
6 | .stylelintcache
7 | *.egg-info/
8 | .ipynb_checkpoints
9 | *.tsbuildinfo
10 | jupyterlab_quickopen/labextension
11 | # Version file is handled by hatchling
12 | jupyterlab_quickopen/_version.py
13 |
14 | # Created by https://www.gitignore.io/api/python
15 | # Edit at https://www.gitignore.io/?templates=python
16 |
17 | ### Python ###
18 | # Byte-compiled / optimized / DLL files
19 | __pycache__/
20 | *.py[cod]
21 | *$py.class
22 |
23 | # C extensions
24 | *.so
25 |
26 | # Distribution / packaging
27 | .Python
28 | build/
29 | develop-eggs/
30 | dist/
31 | downloads/
32 | eggs/
33 | .eggs/
34 | lib/
35 | lib64/
36 | parts/
37 | sdist/
38 | var/
39 | wheels/
40 | pip-wheel-metadata/
41 | share/python-wheels/
42 | .installed.cfg
43 | *.egg
44 | MANIFEST
45 |
46 | # PyInstaller
47 | # Usually these files are written by a python script from a template
48 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
49 | *.manifest
50 | *.spec
51 |
52 | # Installer logs
53 | pip-log.txt
54 | pip-delete-this-directory.txt
55 |
56 | # Unit test / coverage reports
57 | htmlcov/
58 | .tox/
59 | .nox/
60 | .coverage
61 | .coverage.*
62 | .cache
63 | nosetests.xml
64 | coverage/
65 | coverage.xml
66 | *.cover
67 | .hypothesis/
68 | .pytest_cache/
69 |
70 | # Translations
71 | *.mo
72 | *.pot
73 |
74 | # Scrapy stuff:
75 | .scrapy
76 |
77 | # Sphinx documentation
78 | docs/_build/
79 |
80 | # PyBuilder
81 | target/
82 |
83 | # pyenv
84 | .python-version
85 |
86 | # celery beat schedule file
87 | celerybeat-schedule
88 |
89 | # SageMath parsed files
90 | *.sage.py
91 |
92 | # Spyder project settings
93 | .spyderproject
94 | .spyproject
95 |
96 | # Rope project settings
97 | .ropeproject
98 |
99 | # Mr Developer
100 | .mr.developer.cfg
101 | .project
102 | .pydevproject
103 |
104 | # mkdocs documentation
105 | /site
106 |
107 | # mypy
108 | .mypy_cache/
109 | .dmypy.json
110 | dmypy.json
111 |
112 | # Pyre type checker
113 | .pyre/
114 |
115 | # End of https://www.gitignore.io/api/python
116 |
117 | # OSX files
118 | .DS_Store
119 |
120 | # Yarn cache
121 | .yarn/
122 |
123 | # JupyterLab upgrade script
124 | _temp_extension
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | **/node_modules
3 | **/lib
4 | **/package.json
5 | !/package.json
6 | jupyterlab_quickopen
7 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 |
4 |
5 | ## 2.0.2
6 |
7 | ([Full Changelog](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/compare/v2.0.1...3c730b09842fa5fcc3245890ab96d681d1855047))
8 |
9 | ### Bugs fixed
10 |
11 | - Use a relative path because a path cannot start with a drive letter [#65](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/65) ([@yjoer](https://github.com/yjoer))
12 |
13 | ### Contributors to this release
14 |
15 | ([GitHub contributors page for this release](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/graphs/contributors?from=2024-10-09&to=2024-10-21&type=c))
16 |
17 | [@yjoer](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Ayjoer+updated%3A2024-10-09..2024-10-21&type=Issues)
18 |
19 |
20 |
21 | ## 2.0.1
22 |
23 | ([Full Changelog](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/compare/v2.0.0...367d06e09d546089dfe6ea168ba7ccc91f51fcd1))
24 |
25 | ### Bugs fixed
26 |
27 | - Ensure compatibility with both sync and async contents managers [#62](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/62) ([@yjoer](https://github.com/yjoer))
28 |
29 | ### Documentation improvements
30 |
31 | - Add `conda-forge` install to the README [#64](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/64) ([@jtpio](https://github.com/jtpio))
32 | - add apt.text with wamerican to add /usr/share/dict/words [#60](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/60) ([@fomightez](https://github.com/fomightez))
33 | - Add ready badge to the README [#59](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/59) ([@jtpio](https://github.com/jtpio))
34 |
35 | ### Contributors to this release
36 |
37 | ([GitHub contributors page for this release](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/graphs/contributors?from=2024-09-30&to=2024-10-09&type=c))
38 |
39 | [@fomightez](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Afomightez+updated%3A2024-09-30..2024-10-09&type=Issues) | [@github-actions](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Agithub-actions+updated%3A2024-09-30..2024-10-09&type=Issues) | [@jtpio](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Ajtpio+updated%3A2024-09-30..2024-10-09&type=Issues) | [@yjoer](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Ayjoer+updated%3A2024-09-30..2024-10-09&type=Issues)
40 |
41 | ## 2.0.0
42 |
43 | ([Full Changelog](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/compare/1.2.0...ec87ceb2cb87900d45db06f265c8ce7034caa876))
44 |
45 | ### :sparkles: Highlights :sparkles:
46 |
47 | This version adds support for JupyterLab 4.
48 |
49 | It also changes the Quick Open widget to be a modal widget instead of being located in the left area, for consistency with the command palette:
50 |
51 | 
52 |
53 | The shortcut to open the Quick Open widget is Accel Ctrl P. It can also be opened via the `View > Quick Open` menu:
54 |
55 | 
56 |
57 | ### Enhancements made
58 |
59 | - Update to JupyterLab 4 [#48](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/48) ([@jtpio](https://github.com/jtpio))
60 | - Add to the menu [#57](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/57) ([@jtpio](https://github.com/jtpio))
61 |
62 | ### Maintenance and upkeep improvements
63 |
64 | - More cleanups [#55](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/55) ([@jtpio](https://github.com/jtpio))
65 | - Cleanups [#54](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/54) ([@jtpio](https://github.com/jtpio))
66 |
67 | ### Documentation improvements
68 |
69 | - Populate changelog with previous releases [#56](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/56) ([@jtpio](https://github.com/jtpio))
70 | - Fix link to Binder [#53](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/53) ([@jtpio](https://github.com/jtpio))
71 | - Add screencasts to the README [#51](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/51) ([@jtpio](https://github.com/jtpio))
72 |
73 | ### Contributors to this release
74 |
75 | ([GitHub contributors page for this release](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/graphs/contributors?from=2021-12-12&to=2024-09-30&type=c))
76 |
77 | [@github-actions](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Agithub-actions+updated%3A2021-12-12..2024-09-30&type=Issues) | [@jtpio](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Ajtpio+updated%3A2021-12-12..2024-09-30&type=Issues)
78 |
79 | ## 1.2.0
80 |
81 | ([full changelog](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/compare/311f367...dd12b63))
82 |
83 | ### Merged PRs
84 |
85 | - Update for JupyterLab 3.1.x, latest cookiecutter [#29](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/29) ([@parente](https://github.com/parente))
86 |
87 | ### Contributors to this release
88 |
89 | ([GitHub contributors page for this release](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/graphs/contributors?from=2021-08-14&to=2021-12-12&type=c))
90 |
91 | [@parente](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Aparente+updated%3A2021-08-14..2021-12-12&type=Issues)
92 |
93 | ## 1.1.0
94 |
95 | ([full changelog](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/compare/65a2eac...311f367))
96 |
97 | ### Merged PRs
98 |
99 | - Update for JupyterLab 3.1.x, latest cookiecutter [#29](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/29) ([@parente](https://github.com/parente))
100 | - Bump path-parse from 1.0.6 to 1.0.7 [#28](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/28) ([@dependabot](https://github.com/dependabot))
101 | - Bump tar from 6.0.5 to 6.1.5 [#27](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/27) ([@dependabot](https://github.com/dependabot))
102 | - Bump postcss from 7.0.35 to 7.0.36 [#26](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/26) ([@dependabot](https://github.com/dependabot))
103 | - Bump glob-parent from 5.1.1 to 5.1.2 [#25](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/25) ([@dependabot](https://github.com/dependabot))
104 | - Bump normalize-url from 4.5.0 to 4.5.1 [#24](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/24) ([@dependabot](https://github.com/dependabot))
105 | - Bump ws from 7.4.2 to 7.4.6 [#23](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/23) ([@dependabot](https://github.com/dependabot))
106 | - Bump browserslist from 4.16.0 to 4.16.6 [#22](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/22) ([@dependabot](https://github.com/dependabot))
107 | - Bump lodash from 4.17.20 to 4.17.21 [#21](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/21) ([@dependabot](https://github.com/dependabot))
108 | - Bump hosted-git-info from 2.8.8 to 2.8.9 [#20](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/20) ([@dependabot](https://github.com/dependabot))
109 | - Bump ssri from 8.0.0 to 8.0.1 [#19](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/19) ([@dependabot](https://github.com/dependabot))
110 | - Update binder to use jupyter_server [#18](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/18) ([@parente](https://github.com/parente))
111 | - Update extension to work with jupyterlab 3.0 [#17](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/17) ([@parente](https://github.com/parente))
112 |
113 | ### Contributors to this release
114 |
115 | ([GitHub contributors page for this release](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/graphs/contributors?from=2020-12-31&to=2021-08-14&type=c))
116 |
117 | [@dependabot](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Adependabot+updated%3A2020-12-31..2021-08-14&type=Issues) | [@parente](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Aparente+updated%3A2020-12-31..2021-08-14&type=Issues)
118 |
119 | ## 1.0.0
120 |
121 | ([full changelog](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/compare/eb04bd1...65a2eac))
122 |
123 | ### Merged PRs
124 |
125 | - Bump node-fetch from 2.6.0 to 2.6.1 [#15](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/15) ([@dependabot](https://github.com/dependabot))
126 |
127 | ### Contributors to this release
128 |
129 | ([GitHub contributors page for this release](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/graphs/contributors?from=2020-03-20&to=2020-12-31&type=c))
130 |
131 | [@dependabot](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Adependabot+updated%3A2020-03-20..2020-12-31&type=Issues) | [@parente](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Aparente+updated%3A2020-03-20..2020-12-31&type=Issues)
132 |
133 | ## 0.5.0
134 |
135 | ([full changelog](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/compare/ca55830...eb04bd1))
136 |
137 | ### Merged PRs
138 |
139 | - Jupyter 2.0.1 support [#13](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/13) ([@itaistopel](https://github.com/itaistopel))
140 |
141 | ### Contributors to this release
142 |
143 | ([GitHub contributors page for this release](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/graphs/contributors?from=2020-03-07&to=2020-03-20&type=c))
144 |
145 | [@itaistopel](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Aitaistopel+updated%3A2020-03-07..2020-03-20&type=Issues) | [@parente](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Aparente+updated%3A2020-03-07..2020-03-20&type=Issues)
146 |
147 | ## 0.4.1
148 |
149 | ([full changelog](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/compare/6a1e07a...ca55830))
150 |
151 | ### Contributors to this release
152 |
153 | ([GitHub contributors page for this release](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/graphs/contributors?from=2020-03-07&to=2020-03-07&type=c))
154 |
155 | ## 0.4.0
156 |
157 | ([full changelog](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/compare/f7c11a3...6a1e07a))
158 |
159 | ### Contributors to this release
160 |
161 | ([GitHub contributors page for this release](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/graphs/contributors?from=2019-07-28&to=2020-03-07&type=c))
162 |
163 | ## 0.3.0
164 |
165 | ([full changelog](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/compare/e23408a...f7c11a3))
166 |
167 | ### Merged PRs
168 |
169 | - Added relativeSearch functionality [#6](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/6) ([@StevenLaan](https://github.com/StevenLaan))
170 | - Support JupyterLab 1.0 [#5](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/5) ([@parente](https://github.com/parente))
171 |
172 | ### Contributors to this release
173 |
174 | ([GitHub contributors page for this release](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/graphs/contributors?from=2019-06-30&to=2019-07-28&type=c))
175 |
176 | [@parente](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Aparente+updated%3A2019-06-30..2019-07-28&type=Issues) | [@StevenLaan](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3AStevenLaan+updated%3A2019-06-30..2019-07-28&type=Issues)
177 |
178 | ## 0.2.0
179 |
180 | ([full changelog](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/compare/79a935a...e23408a))
181 |
182 | ### Merged PRs
183 |
184 | - Add binder button and tutorial nb [#1](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/pull/1) ([@parente](https://github.com/parente))
185 |
186 | ### Contributors to this release
187 |
188 | ([GitHub contributors page for this release](https://github.com/jupyterlab-contrib/jupyterlab-quickopen/graphs/contributors?from=2018-12-04&to=2019-06-30&type=c))
189 |
190 | [@parente](https://github.com/search?q=repo%3Ajupyterlab-contrib%2Fjupyterlab-quickopen+involves%3Aparente+updated%3A2018-12-04..2019-06-30&type=Issues)
191 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018, 2020 Peter Parente
2 | Copyright (c) JupyterLab Contrib Team
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without modification,
6 | are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this
9 | list of conditions and the following disclaimer.
10 |
11 | 2. Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 |
15 | 3. Neither the name of the copyright holder nor the names of its contributors
16 | may be used to endorse or promote products derived from this software without
17 | specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jupyterlab-quickopen
2 |
3 | [](https://jupyterlab-contrib.github.io/)
4 | [](https://mybinder.org/v2/gh/jupyterlab-contrib/jupyterlab-quickopen/main?urlpath=lab%2Ftree%2Fbinder%2Ftutorial.ipynb)
5 |
6 | Quickly open a file in JupyterLab by typing part of its name
7 |
8 | https://github.com/user-attachments/assets/77567c89-ad52-4be8-b0e4-612700353242
9 |
10 | ## Compatibility
11 |
12 | - Python >=3.8.x
13 | - [JupyterLab](https://github.com/jupyterlab/jupyterlab) >=3.2
14 | - [Jupyter Server](https://github.com/jupyter/jupyter_server) >=2.4
15 | - Configurations where notebook documents and other files reside on a filesystem local to the
16 | Jupyter Server (which is the the default), not remote storage (e.g., S3)
17 |
18 | ## Usage
19 |
20 | After installing the extension, you can open the quick open panel by pressing `Ctrl Shift P` (or `Cmd P` on macOS). Start typing the name of the file you want to open, and the quick open panel will show a list of files that match the text you've typed.
21 |
22 | https://github.com/user-attachments/assets/77567c89-ad52-4be8-b0e4-612700353242
23 |
24 | The extension also works in Jupyter Notebook 7:
25 |
26 | https://github.com/user-attachments/assets/49147847-2b98-4016-8a11-5d0e8d9749e1
27 |
28 | ## Install
29 |
30 | To install the extension with `pip`:
31 |
32 | ```bash
33 | pip install jupyterlab-quickopen
34 | ```
35 |
36 | With `conda` / `mamba`:
37 |
38 | ```bash
39 | conda install -c conda-forge jupyterlab-quickopen
40 | ```
41 |
42 | ## Configure
43 |
44 | ### Using a custom Keyboard Shortcut
45 |
46 | The default keyboard shortcut for opening the quickopen panel is `Accel Ctrl P`.
47 |
48 | You can assign your own keyboard shortcut to show the quickopen panel at any time. Open the keyboard editor
49 | by clicking _Settings → Advanced Settings Editor → Keyboard Shortcuts_. Then enter JSON in
50 | the _User Overrides_ text area like the following, adjusting the `keys` value to assign the shortcut
51 | of your choosing:
52 |
53 | ```json
54 | {
55 | "shortcuts": [
56 | {
57 | "command": "quickopen:activate",
58 | "keys": ["Accel Ctrl P"],
59 | "selector": "body",
60 | "title": "Activate Quick Open",
61 | "category": "Main Area"
62 | }
63 | ]
64 | }
65 | ```
66 |
67 | ### Patterns to Exclude
68 |
69 | You can control which files to exclude from the quick open list using the Jupyter Server settings,
70 | JupyterLab settings, or both.
71 |
72 | On the server side, use the `ContentsManager.allow_hidden` and/or `ContentsManager.hide_globs`
73 | settings. See the
74 | [documentation about Jupyter Server options](https://jupyter-server.readthedocs.io/en/latest/operators/configuring-extensions.html)
75 | for details.
76 |
77 | In the JupyterLab web app, open the _Settings_ menu, click the _Advanced Settings Editor_ option,
78 | select the _Quick Open_ item in the _Raw View_ sidebar, and enter JSON in the _User Overrides_ text
79 | area to override the default values.
80 |
81 | 
82 |
83 | ### Development install
84 |
85 | Note: You will need NodeJS to build the extension package.
86 |
87 | The `jlpm` command is JupyterLab's pinned version of
88 | [yarn](https://yarnpkg.com/) that is installed with JupyterLab. You may use
89 | `yarn` or `npm` in lieu of `jlpm` below.
90 |
91 | ```bash
92 | # Clone the repo to your local environment
93 | # Change directory to the jupyterlab_quickopen directory
94 | # Install package in development mode
95 | pip install -e .
96 | # Link your development version of the extension with JupyterLab
97 | jupyter labextension develop . --overwrite
98 | # Server extension must be manually installed in develop mode
99 | jupyter server extension enable jupyterlab_quickopen
100 | # Rebuild extension Typescript source after making changes
101 | jlpm build
102 | ```
103 |
104 | You can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the extension.
105 |
106 | ```bash
107 | # Watch the source directory in one terminal, automatically rebuilding when needed
108 | jlpm watch
109 | # Run JupyterLab in another terminal
110 | jupyter lab
111 | ```
112 |
113 | With the watch command running, every saved change will immediately be built locally and available in your running JupyterLab. Refresh JupyterLab to load the change in your browser (you may need to wait several seconds for the extension to be rebuilt).
114 |
115 | By default, the `jlpm build` command generates the source maps for this extension to make it easier to debug using the browser dev tools. To also generate source maps for the JupyterLab core extensions, you can run the following command:
116 |
117 | ```bash
118 | jupyter lab build --minimize=False
119 | ```
120 |
121 | ### Releasing
122 |
123 | See [RELEASE](RELEASE.md)
124 |
125 | ### Acknowledgements
126 |
127 | This extension was originally created by [Peter Parente](https://github.com/parente) and was
128 | later moved to the `jupyterlab-contrib` GitHub organization.
129 |
--------------------------------------------------------------------------------
/RELEASE.md:
--------------------------------------------------------------------------------
1 | # Making a new release of jupyterlab_quickopen
2 |
3 | The extension can be published to `PyPI` and `npm` manually or using the [Jupyter Releaser](https://github.com/jupyter-server/jupyter_releaser).
4 |
5 | ## Manual release
6 |
7 | ### Python package
8 |
9 | This extension can be distributed as Python packages. All of the Python
10 | packaging instructions are in the `pyproject.toml` file to wrap your extension in a
11 | Python package. Before generating a package, you first need to install some tools:
12 |
13 | ```bash
14 | pip install build twine hatch
15 | ```
16 |
17 | Bump the version using `hatch`. By default this will create a tag.
18 | See the docs on [hatch-nodejs-version](https://github.com/agoose77/hatch-nodejs-version#semver) for details.
19 |
20 | ```bash
21 | hatch version
22 | ```
23 |
24 | Make sure to clean up all the development files before building the package:
25 |
26 | ```bash
27 | jlpm clean:all
28 | ```
29 |
30 | You could also clean up the local git repository:
31 |
32 | ```bash
33 | git clean -dfX
34 | ```
35 |
36 | To create a Python source package (`.tar.gz`) and the binary package (`.whl`) in the `dist/` directory, do:
37 |
38 | ```bash
39 | python -m build
40 | ```
41 |
42 | > `python setup.py sdist bdist_wheel` is deprecated and will not work for this package.
43 |
44 | Then to upload the package to PyPI, do:
45 |
46 | ```bash
47 | twine upload dist/*
48 | ```
49 |
50 | ### NPM package
51 |
52 | To publish the frontend part of the extension as a NPM package, do:
53 |
54 | ```bash
55 | npm login
56 | npm publish --access public
57 | ```
58 |
59 | ## Automated releases with the Jupyter Releaser
60 |
61 | The extension repository should already be compatible with the Jupyter Releaser. But
62 | the GitHub repository and the package managers need to be properly set up. Please
63 | follow the instructions of the Jupyter Releaser [checklist](https://jupyter-releaser.readthedocs.io/en/latest/how_to_guides/convert_repo_from_repo.html).
64 |
65 | Here is a summary of the steps to cut a new release:
66 |
67 | - Go to the Actions panel
68 | - Run the "Step 1: Prep Release" workflow
69 | - Check the draft changelog
70 | - Run the "Step 2: Publish Release" workflow
71 |
72 | > [!NOTE]
73 | > Check out the [workflow documentation](https://jupyter-releaser.readthedocs.io/en/latest/get_started/making_release_from_repo.html)
74 | > for more information.
75 |
76 | ## Publishing to `conda-forge`
77 |
78 | If the package is not on conda forge yet, check the documentation to learn how to add it: https://conda-forge.org/docs/maintainer/adding_pkgs.html
79 |
80 | Otherwise a bot should pick up the new version publish to PyPI, and open a new PR on the feedstock repository automatically.
81 |
--------------------------------------------------------------------------------
/binder/apt.txt:
--------------------------------------------------------------------------------
1 | wamerican
--------------------------------------------------------------------------------
/binder/environment.yml:
--------------------------------------------------------------------------------
1 | # a mybinder.org-ready environment for demoing jupyterlab_quickopen
2 | # this environment may also be used locally on Linux/MacOS/Windows, e.g.
3 | #
4 | # conda env update --file binder/environment.yml
5 | # conda activate jupyterlab-quickopen-demo
6 | #
7 | name: jupyterlab-quickopen-demo
8 |
9 | channels:
10 | - conda-forge
11 |
12 | dependencies:
13 | # runtime dependencies
14 | - python >=3.10,<3.11.0a0
15 | - jupyterlab >=4.0.0,<5
16 | # labextension build dependencies
17 | - nodejs >=18,<19
18 | - pip
19 | - wheel
20 | # additional packages for demos
21 | # - ipywidgets
22 |
--------------------------------------------------------------------------------
/binder/postBuild:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """ perform a development install of jupyterlab_quickopen
3 |
4 | On Binder, this will run _after_ the environment has been fully created from
5 | the environment.yml in this directory.
6 |
7 | This script should also run locally on Linux/MacOS/Windows:
8 |
9 | python3 binder/postBuild
10 | """
11 | import subprocess
12 | import sys
13 | from pathlib import Path
14 |
15 |
16 | ROOT = Path.cwd()
17 |
18 | def _(*args, **kwargs):
19 | """ Run a command, echoing the args
20 |
21 | fails hard if something goes wrong
22 | """
23 | print("\n\t", " ".join(args), "\n")
24 | return_code = subprocess.call(args, **kwargs)
25 | if return_code != 0:
26 | print("\nERROR", return_code, " ".join(args))
27 | sys.exit(return_code)
28 |
29 | # verify the environment is self-consistent before even starting
30 | _(sys.executable, "-m", "pip", "check")
31 |
32 | # install the labextension
33 | _(sys.executable, "-m", "pip", "install", "-e", ".")
34 | _(sys.executable, "-m", "jupyter", "labextension", "develop", "--overwrite", ".")
35 | _(
36 | sys.executable,
37 | "-m",
38 | "jupyter",
39 | "server",
40 | "extension",
41 | "enable",
42 | "jupyterlab_quickopen",
43 | )
44 |
45 | # verify the environment the extension didn't break anything
46 | _(sys.executable, "-m", "pip", "check")
47 |
48 | # list the extensions
49 | _("jupyter", "server", "extension", "list")
50 |
51 | # initially list installed extensions to determine if there are any surprises
52 | _("jupyter", "labextension", "list")
53 |
54 |
55 | print("JupyterLab with jupyterlab_quickopen is ready to run with:\n")
56 | print("\tjupyter lab\n")
57 |
--------------------------------------------------------------------------------
/binder/tutorial.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Tutorial: jupyterlab-quickopen\n",
8 | "\n",
9 | "This notebook is a short, hands-on tutorial about using the JupyterLab quick open extension.\n",
10 | "\n",
11 | "First, assign a hotkey to the extension so you don't have to click the little magnifying glass in the sidebar every time you want to search.\n",
12 | "\n",
13 | "1. Click the *Settings* menu then → *Advanced Settings Editor*.\n",
14 | "2. Select *Keyboard Shortcuts* in the dialog that opens.\n",
15 | "3. Add the following to the JSON in the right panel to assign `Ctrl-Cmd-P` as the hotkey on Mac and `Ctrl-Alt-P` on Windows/Linux.\n",
16 | "\n",
17 | "```\n",
18 | "{\n",
19 | " \"shortcuts\": [\n",
20 | " {\n",
21 | " \"command\": \"quickopen:activate\",\n",
22 | " \"keys\": [\n",
23 | " \"Accel Ctrl P\"\n",
24 | " ],\n",
25 | " \"selector\": \"body\",\n",
26 | " \"title\": \"Activate Quick Open\",\n",
27 | " \"category\": \"Main Area\"\n",
28 | " }\n",
29 | " ]\n",
30 | "}\n",
31 | "```\n",
32 | "\n",
33 | "4. Hit the same button in the top-right."
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "Now, try to find and open the `LICENSE` file included in this repo. \n",
41 | "\n",
42 | "1. Press the hotkey you just assigned and the quick open sidebar panel should appear. \n",
43 | "2. Type *lic* and the panel should show only those paths in your notebook directory containing the letters \"l\", \"i\", and \"c\", in that order.\n",
44 | "3. Use the arrow keys to select the `LICENSE` file (it's probably already selected).\n",
45 | "4. Press *Enter* to open it."
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "Run the code below to generate a thousand more files in the notebook tree."
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "import os\n",
62 | "import random\n",
63 | "\n",
64 | "# Get a thousand words\n",
65 | "with open('/usr/share/dict/words') as fh:\n",
66 | " words = fh.readlines()\n",
67 | "words = random.choices([w.strip() for w in words if \"'\" not in w], k=1000)\n",
68 | "\n",
69 | "# Make filenames from those words\n",
70 | "os.makedirs('data', exist_ok=True)\n",
71 | "for w in words:\n",
72 | " with open(f'data/{w}.txt', 'w') as fh:\n",
73 | " fh.write(w)"
74 | ]
75 | },
76 | {
77 | "cell_type": "markdown",
78 | "metadata": {},
79 | "source": [
80 | "Use the quick open sidebar to find these five generated files. "
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": null,
86 | "metadata": {},
87 | "outputs": [],
88 | "source": [
89 | "words[:5]"
90 | ]
91 | }
92 | ],
93 | "metadata": {
94 | "kernelspec": {
95 | "display_name": "Python 3 (ipykernel)",
96 | "language": "python",
97 | "name": "python3"
98 | },
99 | "language_info": {
100 | "codemirror_mode": {
101 | "name": "ipython",
102 | "version": 3
103 | },
104 | "file_extension": ".py",
105 | "mimetype": "text/x-python",
106 | "name": "python",
107 | "nbconvert_exporter": "python",
108 | "pygments_lexer": "ipython3",
109 | "version": "3.12.5"
110 | },
111 | "nteract": {
112 | "version": "0.10.0"
113 | }
114 | },
115 | "nbformat": 4,
116 | "nbformat_minor": 4
117 | }
118 |
--------------------------------------------------------------------------------
/doc/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyterlab-contrib/jupyterlab-quickopen/154c60f657ed9e6ec20c7836be92f11c4b23eff5/doc/settings.png
--------------------------------------------------------------------------------
/install.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageManager": "python",
3 | "packageName": "jupyterlab-quickopen",
4 | "uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package jupyterlab-quickopen"
5 | }
6 |
--------------------------------------------------------------------------------
/jupyter-config/server-config/jupyterlab_quickopen.json:
--------------------------------------------------------------------------------
1 | {
2 | "ServerApp": {
3 | "jpserver_extensions": {
4 | "jupyterlab_quickopen": true
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/jupyterlab_quickopen/__init__.py:
--------------------------------------------------------------------------------
1 | """Registers the jupyterlab front and backend quickopen extensions"""
2 | try:
3 | from ._version import __version__
4 | except ImportError:
5 | # Fallback when using the package in dev mode without installing
6 | # in editable mode with pip. It is highly recommended to install
7 | # the package from a stable release or in editable mode: https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs
8 | import warnings
9 | warnings.warn("Importing 'jupyterlab_quickopen' outside a proper installation.")
10 | __version__ = "dev"
11 |
12 | from pathlib import Path
13 | from .handler import QuickOpenHandler
14 | from jupyter_server.utils import url_path_join
15 |
16 |
17 | def _jupyter_labextension_paths():
18 | return [{"src": "labextension", "dest": "jupyterlab-quickopen"}]
19 |
20 |
21 | def _jupyter_server_extension_points():
22 | return [{"module": "jupyterlab_quickopen"}]
23 |
24 |
25 | def _load_jupyter_server_extension(server_app):
26 | """Registers the API handler to receive HTTP requests from the frontend extension.
27 |
28 | Parameters
29 | ----------
30 | server_app: jupyterlab.labapp.LabApp
31 | JupyterLab application instance
32 | """
33 | server_app.log.debug("notebook_dir: %s", server_app.notebook_dir)
34 | server_app.log.debug(
35 | "contents_manager.root_dir: %s", server_app.contents_manager.root_dir
36 | )
37 | if (
38 | not Path(server_app.root_dir).is_dir()
39 | or server_app.contents_manager.root_dir != server_app.root_dir
40 | ):
41 | server_app.log.info(
42 | f"Refusing to register QuickOpenHandler extension: "
43 | f"{server_app.contents_manager} does not appear to load from the local filesystem"
44 | )
45 | return
46 |
47 | web_app = server_app.web_app
48 | host_pattern = ".*$"
49 | route_pattern = url_path_join(
50 | web_app.settings["base_url"], "jupyterlab-quickopen", "api", "files"
51 | )
52 | web_app.add_handlers(host_pattern, [(route_pattern, QuickOpenHandler)])
53 | server_app.log.info(
54 | f"Registered QuickOpenHandler extension at URL path {route_pattern} "
55 | f"to serve results of scanning local path {server_app.notebook_dir}"
56 | )
57 |
--------------------------------------------------------------------------------
/jupyterlab_quickopen/handler.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 |
4 | from fnmatch import fnmatch
5 |
6 | from jupyter_server.base.handlers import APIHandler
7 | from jupyter_server.utils import ensure_async
8 | from tornado import web
9 | from tornado.escape import json_encode
10 |
11 |
12 | class QuickOpenHandler(APIHandler):
13 | @property
14 | def contents_manager(self):
15 | """Currently configured jupyter server ContentsManager."""
16 | return self.settings["contents_manager"]
17 |
18 | @property
19 | def root_dir(self):
20 | """Root directory to scan."""
21 | return self.contents_manager.root_dir
22 |
23 | async def should_hide(self, entry, excludes):
24 | """Decides if a file or directory should be hidden from the search results based on
25 | the `allow_hidden` and `hide_globs` properties of the ContentsManager, as well as a
26 | set of exclude patterns included in the client request.
27 |
28 | Parameters
29 | ----------
30 | entry: DirEntry
31 | From os.scandir
32 | excludes: set of str
33 | Exclude patterns
34 |
35 | Returns
36 | -------
37 | bool
38 | """
39 | relpath = os.path.relpath(entry.path)
40 |
41 | return (
42 | any(fnmatch(entry.name, glob) for glob in excludes)
43 | or not self.contents_manager.should_list(entry.name)
44 | or (
45 | await ensure_async(self.contents_manager.is_hidden(relpath))
46 | and not self.contents_manager.allow_hidden
47 | )
48 | )
49 |
50 | async def scan_disk(self, path, excludes, on_disk=None):
51 | if on_disk is None:
52 | on_disk = {}
53 | for entry in os.scandir(path):
54 | if await self.should_hide(entry, excludes):
55 | continue
56 | elif entry.is_dir():
57 | await self.scan_disk(entry.path, excludes, on_disk)
58 | elif entry.is_file():
59 | parent = os.path.relpath(os.path.dirname(entry.path), self.root_dir)
60 | on_disk.setdefault(parent, []).append(entry.name)
61 | return on_disk
62 |
63 | @web.authenticated
64 | async def get(self):
65 | """Gets the name of every file under the root notebooks directory binned by parent
66 | folder relative to the root notebooks dir.
67 |
68 | Arguments
69 | ---------
70 | exclude: str
71 | Comma-separated set of file name patterns to exclude
72 |
73 | Responds
74 | --------
75 | JSON
76 | scan_seconds: Time in seconds to collect all file names
77 | contents: File names binned by parent directory
78 | """
79 | excludes = set(self.get_arguments("excludes"))
80 | current_path = self.get_argument("path")
81 | start_ts = time.time()
82 | if current_path:
83 | full_path = os.path.join(self.root_dir, current_path)
84 | else:
85 | full_path = self.root_dir
86 | contents_by_path = await self.scan_disk(full_path, excludes)
87 | delta_ts = time.time() - start_ts
88 | self.write(
89 | json_encode({"scan_seconds": delta_ts, "contents": contents_by_path})
90 | )
91 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jupyterlab-quickopen",
3 | "version": "2.0.2",
4 | "description": "Quickly open a file in JupyterLab by part of its name",
5 | "keywords": [
6 | "jupyter",
7 | "jupyterlab",
8 | "jupyterlab-extension"
9 | ],
10 | "homepage": "https://github.com/jupyterlab-contrib/jupyterlab-quickopen",
11 | "bugs": {
12 | "url": "https://github.com/jupyterlab-contrib/jupyterlab-quickopen/issues"
13 | },
14 | "license": "BSD-3-Clause",
15 | "author": {
16 | "name": "JupyterLab Contrib Team",
17 | "email": ""
18 | },
19 | "files": [
20 | "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
21 | "style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}",
22 | "schema/*.json",
23 | "style/index.js"
24 | ],
25 | "main": "lib/index.js",
26 | "types": "lib/index.d.ts",
27 | "style": "style/index.css",
28 | "repository": {
29 | "type": "git",
30 | "url": "https://github.com/jupyterlab-contrib/jupyterlab-quickopen.git"
31 | },
32 | "scripts": {
33 | "build": "jlpm build:lib && jlpm build:labextension:dev",
34 | "build:labextension": "jupyter labextension build .",
35 | "build:labextension:dev": "jupyter labextension build --development True .",
36 | "build:lib": "tsc --sourceMap",
37 | "build:lib:prod": "tsc",
38 | "build:prod": "jlpm clean && jlpm build:lib:prod && jlpm build:labextension",
39 | "clean": "jlpm clean:lib",
40 | "clean:all": "jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache",
41 | "clean:labextension": "rimraf jupyterlab_quickopen/labextension jupyterlab_quickopen/_version.py",
42 | "clean:lib": "rimraf lib tsconfig.tsbuildinfo",
43 | "clean:lintcache": "rimraf .eslintcache .stylelintcache",
44 | "eslint": "jlpm eslint:check --fix",
45 | "eslint:check": "eslint . --cache --ext .ts,.tsx",
46 | "install:extension": "jlpm build",
47 | "lint": "jlpm stylelint && jlpm prettier && jlpm eslint",
48 | "lint:check": "jlpm stylelint:check && jlpm prettier:check && jlpm eslint:check",
49 | "prettier": "jlpm prettier:base --write --list-different",
50 | "prettier:base": "prettier \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md}\"",
51 | "prettier:check": "jlpm prettier:base --check",
52 | "stylelint": "jlpm stylelint:check --fix",
53 | "stylelint:check": "stylelint --cache \"style/**/*.css\"",
54 | "watch": "run-p watch:src watch:labextension",
55 | "watch:labextension": "jupyter labextension watch .",
56 | "watch:src": "tsc -w --sourceMap"
57 | },
58 | "dependencies": {
59 | "@jupyterlab/application": "^4.2.5",
60 | "@jupyterlab/apputils": "^4.3.5",
61 | "@jupyterlab/coreutils": "^6.2.5",
62 | "@jupyterlab/docmanager": "^4.2.5",
63 | "@jupyterlab/filebrowser": "^4.2.5",
64 | "@jupyterlab/services": "^7.2.5",
65 | "@jupyterlab/settingregistry": "^4.2.5",
66 | "@jupyterlab/translation": "^4.2.5"
67 | },
68 | "devDependencies": {
69 | "@jupyterlab/builder": "^4.0.0",
70 | "@types/json-schema": "^7.0.11",
71 | "@types/react": "^18.0.26",
72 | "@types/react-addons-linked-state-mixin": "^0.14.22",
73 | "@typescript-eslint/eslint-plugin": "^6.1.0",
74 | "@typescript-eslint/parser": "^6.1.0",
75 | "css-loader": "^6.7.1",
76 | "eslint": "^8.36.0",
77 | "eslint-config-prettier": "^8.8.0",
78 | "eslint-plugin-prettier": "^5.0.0",
79 | "mkdirp": "^1.0.3",
80 | "npm-run-all": "^4.1.5",
81 | "prettier": "^3.0.0",
82 | "rimraf": "^5.0.1",
83 | "source-map-loader": "^1.0.2",
84 | "style-loader": "^3.3.1",
85 | "stylelint": "^15.10.1",
86 | "stylelint-config-recommended": "^13.0.0",
87 | "stylelint-config-standard": "^34.0.0",
88 | "stylelint-csstree-validator": "^3.0.0",
89 | "stylelint-prettier": "^4.0.0",
90 | "typescript": "~5.0.2",
91 | "yjs": "^13.5.40"
92 | },
93 | "packageManager": "yarn@3.5.0",
94 | "sideEffects": [
95 | "style/*.css",
96 | "style/index.js"
97 | ],
98 | "styleModule": "style/index.js",
99 | "publishConfig": {
100 | "access": "public"
101 | },
102 | "jupyterlab": {
103 | "extension": true,
104 | "discovery": {
105 | "server": {
106 | "managers": [
107 | "pip"
108 | ],
109 | "base": {
110 | "name": "jupyterlab_quickopen"
111 | }
112 | }
113 | },
114 | "schemaDir": "schema",
115 | "outputDir": "jupyterlab_quickopen/labextension"
116 | },
117 | "eslintConfig": {
118 | "extends": [
119 | "eslint:recommended",
120 | "plugin:@typescript-eslint/eslint-recommended",
121 | "plugin:@typescript-eslint/recommended",
122 | "plugin:prettier/recommended"
123 | ],
124 | "parser": "@typescript-eslint/parser",
125 | "parserOptions": {
126 | "project": "tsconfig.json",
127 | "sourceType": "module"
128 | },
129 | "plugins": [
130 | "@typescript-eslint"
131 | ],
132 | "rules": {
133 | "@typescript-eslint/naming-convention": [
134 | "error",
135 | {
136 | "selector": "interface",
137 | "format": [
138 | "PascalCase"
139 | ],
140 | "custom": {
141 | "regex": "^I[A-Z]",
142 | "match": true
143 | }
144 | }
145 | ],
146 | "@typescript-eslint/no-unused-vars": [
147 | "warn",
148 | {
149 | "args": "none"
150 | }
151 | ],
152 | "@typescript-eslint/no-explicit-any": "off",
153 | "@typescript-eslint/no-namespace": "off",
154 | "@typescript-eslint/no-use-before-define": "off",
155 | "@typescript-eslint/quotes": [
156 | "error",
157 | "single",
158 | {
159 | "avoidEscape": true,
160 | "allowTemplateLiterals": false
161 | }
162 | ],
163 | "curly": [
164 | "error",
165 | "all"
166 | ],
167 | "eqeqeq": "error",
168 | "prefer-arrow-callback": "error"
169 | }
170 | },
171 | "eslintIgnore": [
172 | "node_modules",
173 | "dist",
174 | "coverage",
175 | "**/*.d.ts"
176 | ],
177 | "prettier": {
178 | "singleQuote": true,
179 | "trailingComma": "none",
180 | "arrowParens": "avoid",
181 | "endOfLine": "auto",
182 | "overrides": [
183 | {
184 | "files": "package.json",
185 | "options": {
186 | "tabWidth": 4
187 | }
188 | }
189 | ]
190 | },
191 | "stylelint": {
192 | "extends": [
193 | "stylelint-config-recommended",
194 | "stylelint-config-standard",
195 | "stylelint-prettier/recommended"
196 | ],
197 | "plugins": [
198 | "stylelint-csstree-validator"
199 | ],
200 | "rules": {
201 | "csstree/validator": true,
202 | "property-no-vendor-prefix": null,
203 | "selector-class-pattern": "^([a-z][A-z\\d]*)(-[A-z\\d]+)*$",
204 | "selector-no-vendor-prefix": null,
205 | "value-no-vendor-prefix": null
206 | }
207 | }
208 | }
209 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["hatchling>=1.5.0", "jupyterlab>=4.0.0,<5", "hatch-nodejs-version>=0.3.2"]
3 | build-backend = "hatchling.build"
4 |
5 | [project]
6 | name = "jupyterlab-quickopen"
7 | readme = "README.md"
8 | license = { file = "LICENSE" }
9 | requires-python = ">=3.8"
10 | classifiers = [
11 | "Framework :: Jupyter",
12 | "Framework :: Jupyter :: JupyterLab",
13 | "Framework :: Jupyter :: JupyterLab :: 4",
14 | "Framework :: Jupyter :: JupyterLab :: Extensions",
15 | "Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt",
16 | "License :: OSI Approved :: BSD License",
17 | "Programming Language :: Python",
18 | "Programming Language :: Python :: 3",
19 | "Programming Language :: Python :: 3.8",
20 | "Programming Language :: Python :: 3.9",
21 | "Programming Language :: Python :: 3.10",
22 | "Programming Language :: Python :: 3.11",
23 | "Programming Language :: Python :: 3.12",
24 | ]
25 | dependencies = [
26 | "jupyter_server>=2.4.2,<3"
27 | ]
28 | dynamic = ["version", "description", "authors", "urls", "keywords"]
29 |
30 | [tool.hatch.version]
31 | source = "nodejs"
32 |
33 | [tool.hatch.metadata.hooks.nodejs]
34 | fields = ["description", "authors", "urls", "keywords"]
35 |
36 | [tool.hatch.build.targets.sdist]
37 | artifacts = ["jupyterlab_quickopen/labextension"]
38 | exclude = [".github", "binder"]
39 |
40 | [tool.hatch.build.targets.wheel.shared-data]
41 | "jupyterlab_quickopen/labextension" = "share/jupyter/labextensions/jupyterlab-quickopen"
42 | "install.json" = "share/jupyter/labextensions/jupyterlab-quickopen/install.json"
43 | "jupyter-config/server-config" = "etc/jupyter/jupyter_server_config.d"
44 |
45 | [tool.hatch.build.hooks.version]
46 | path = "jupyterlab_quickopen/_version.py"
47 |
48 | [tool.hatch.build.hooks.jupyter-builder]
49 | dependencies = ["hatch-jupyter-builder>=0.5"]
50 | build-function = "hatch_jupyter_builder.npm_builder"
51 | ensured-targets = [
52 | "jupyterlab_quickopen/labextension/static/style.js",
53 | "jupyterlab_quickopen/labextension/package.json",
54 | ]
55 | skip-if-exists = ["jupyterlab_quickopen/labextension/static/style.js"]
56 |
57 | [tool.hatch.build.hooks.jupyter-builder.build-kwargs]
58 | build_cmd = "build:prod"
59 | npm = ["jlpm"]
60 |
61 | [tool.hatch.build.hooks.jupyter-builder.editable-build-kwargs]
62 | build_cmd = "install:extension"
63 | npm = ["jlpm"]
64 | source_dir = "src"
65 | build_dir = "jupyterlab_quickopen/labextension"
66 |
67 | [tool.jupyter-releaser.options]
68 | version_cmd = "hatch version"
69 |
70 | [tool.jupyter-releaser.hooks]
71 | before-build-npm = [
72 | "python -m pip install 'jupyterlab>=4.0.0,<5'",
73 | "jlpm",
74 | "jlpm build:prod"
75 | ]
76 | before-build-python = ["jlpm clean:all"]
77 |
78 | [tool.check-wheel-contents]
79 | ignore = ["W002"]
80 |
--------------------------------------------------------------------------------
/schema/plugin.json:
--------------------------------------------------------------------------------
1 | {
2 | "jupyter.lab.setting-icon-class": "jp-SearchIcon",
3 | "jupyter.lab.setting-icon-label": "Quick Open",
4 | "title": "Quick Open",
5 | "description": "Quick open panel settings",
6 | "properties": {
7 | "excludes": {
8 | "title": "Exclude Patterns",
9 | "description": "File and directory patterns to exclude from the list",
10 | "type": "array",
11 | "items": { "type": "string" },
12 | "default": ["node_modules", "__pycache__"]
13 | },
14 | "relativeSearch": {
15 | "title": "Relative Search",
16 | "description": "Whether to search from currently selected directory",
17 | "type": "boolean",
18 | "default": false
19 | }
20 | },
21 | "jupyter.lab.menus": {
22 | "main": [
23 | {
24 | "id": "jp-mainmenu-view",
25 | "items": [
26 | {
27 | "command": "quickopen:activate",
28 | "rank": 1
29 | },
30 | {
31 | "type": "separator",
32 | "rank": 1
33 | }
34 | ]
35 | }
36 | ]
37 | },
38 | "jupyter.lab.shortcuts": [
39 | {
40 | "command": "quickopen:activate",
41 | "keys": ["Accel Shift P"],
42 | "selector": "body"
43 | }
44 | ],
45 | "additionalProperties": false,
46 | "type": "object"
47 | }
48 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | __import__("setuptools").setup()
2 |
--------------------------------------------------------------------------------
/src/handler.ts:
--------------------------------------------------------------------------------
1 | import { URLExt } from '@jupyterlab/coreutils';
2 |
3 | import { ServerConnection } from '@jupyterlab/services';
4 |
5 | /**
6 | * Call the API extension
7 | *
8 | * @param endPoint API REST end point for the extension
9 | * @param init Initial values for the request
10 | * @returns The response body interpreted as JSON
11 | */
12 | export async function requestAPI(
13 | endPoint = '',
14 | init: RequestInit = {}
15 | ): Promise {
16 | // Make request to Jupyter API
17 | const settings = ServerConnection.makeSettings();
18 | const requestUrl = URLExt.join(
19 | settings.baseUrl,
20 | 'jupyterlab-quickopen', // API Namespace
21 | endPoint
22 | );
23 |
24 | let response: Response;
25 | try {
26 | response = await ServerConnection.makeRequest(requestUrl, init, settings);
27 | } catch (error) {
28 | throw new ServerConnection.NetworkError(error as any);
29 | }
30 |
31 | let data: any = await response.text();
32 |
33 | if (data.length > 0) {
34 | try {
35 | data = JSON.parse(data);
36 | } catch (error) {
37 | console.log('Not a JSON response body.', response);
38 | }
39 | }
40 |
41 | if (!response.ok) {
42 | throw new ServerConnection.ResponseError(response, data.message || data);
43 | }
44 |
45 | return data;
46 | }
47 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | JupyterFrontEnd,
3 | JupyterFrontEndPlugin
4 | } from '@jupyterlab/application';
5 | import { ICommandPalette, ModalCommandPalette } from '@jupyterlab/apputils';
6 | import { URLExt, PathExt } from '@jupyterlab/coreutils';
7 | import { IDocumentManager } from '@jupyterlab/docmanager';
8 | import { ServerConnection } from '@jupyterlab/services';
9 | import { ISettingRegistry } from '@jupyterlab/settingregistry';
10 | import { FileBrowser, IDefaultFileBrowser } from '@jupyterlab/filebrowser';
11 | import { ITranslator, nullTranslator } from '@jupyterlab/translation';
12 | import { CommandRegistry } from '@lumino/commands';
13 | import { ReadonlyPartialJSONObject } from '@lumino/coreutils';
14 | import { Message } from '@lumino/messaging';
15 | import { ISignal, Signal } from '@lumino/signaling';
16 | import { CommandPalette } from '@lumino/widgets';
17 |
18 | /** Structure of the JSON response from the server */
19 | interface IQuickOpenResponse {
20 | readonly contents: { [key: string]: string[] };
21 | readonly scanSeconds: number;
22 | }
23 |
24 | /** Makes a HTTP request for the server-side quick open scan */
25 | async function fetchContents(
26 | path: string,
27 | excludes: string[]
28 | ): Promise {
29 | const query = excludes
30 | .map(exclude => {
31 | return 'excludes=' + encodeURIComponent(exclude);
32 | })
33 | .join('&');
34 |
35 | const settings = ServerConnection.makeSettings();
36 | const fullUrl =
37 | URLExt.join(settings.baseUrl, 'jupyterlab-quickopen', 'api', 'files') +
38 | '?' +
39 | query +
40 | '&path=' +
41 | path;
42 | const response = await ServerConnection.makeRequest(
43 | fullUrl,
44 | { method: 'GET' },
45 | settings
46 | );
47 | if (response.status !== 200) {
48 | throw new ServerConnection.ResponseError(response);
49 | }
50 | return await response.json();
51 | }
52 |
53 | /**
54 | * Shows files nested under directories in the root notebooks directory configured on the server.
55 | */
56 | class QuickOpenWidget extends CommandPalette {
57 | private _pathSelected = new Signal(this);
58 | private _settings: ReadonlyPartialJSONObject;
59 | private _fileBrowser: FileBrowser;
60 |
61 | constructor(
62 | defaultBrowser: IDefaultFileBrowser,
63 | settings: ReadonlyPartialJSONObject,
64 | options: CommandPalette.IOptions
65 | ) {
66 | super(options);
67 |
68 | this.id = 'jupyterlab-quickopen';
69 | this.title.iconClass = 'jp-SideBar-tabIcon jp-SearchIcon';
70 | this.title.caption = 'Quick Open';
71 |
72 | this._settings = settings;
73 | this._fileBrowser = defaultBrowser;
74 | }
75 |
76 | /** Signal when a selected path is activated. */
77 | get pathSelected(): ISignal {
78 | return this._pathSelected;
79 | }
80 |
81 | /** Current extension settings */
82 | set settings(settings: ReadonlyPartialJSONObject) {
83 | this._settings = settings;
84 | }
85 |
86 | /**
87 | * Refreshes the widget with the paths of files on the server.
88 | */
89 | protected async onActivateRequest(msg: Message): Promise {
90 | super.onActivateRequest(msg);
91 |
92 | // Fetch the current contents from the server
93 | const path = this._settings.relativeSearch
94 | ? this._fileBrowser.model.path
95 | : '';
96 | const response = await fetchContents(
97 | path,
98 | this._settings.excludes as string[]
99 | );
100 |
101 | // Remove all paths from the view
102 | this.clearItems();
103 |
104 | for (const category in response.contents) {
105 | for (const fn of response.contents[category]) {
106 | // Creates commands that are relative file paths on the server
107 | const command = `${category}/${fn}`;
108 | if (!this.commands.hasCommand(command)) {
109 | // Only add the command to the registry if it does not yet exist TODO: Track disposables
110 | // and remove
111 | this.commands.addCommand(command, {
112 | label: fn,
113 | execute: () => {
114 | // Emit a selection signal
115 | this._pathSelected.emit(command);
116 | }
117 | });
118 | }
119 | // Make the file visible under its parent directory heading
120 | this.addItem({ command, category });
121 | }
122 | }
123 | }
124 | }
125 |
126 | /**
127 | * Initialization data for the jupyterlab-quickopen extension.
128 | */
129 | const extension: JupyterFrontEndPlugin = {
130 | id: 'jupyterlab-quickopen:plugin',
131 | autoStart: true,
132 | requires: [IDocumentManager, ISettingRegistry, IDefaultFileBrowser],
133 | optional: [ICommandPalette, ITranslator],
134 | activate: async (
135 | app: JupyterFrontEnd,
136 | docManager: IDocumentManager,
137 | settingRegistry: ISettingRegistry,
138 | defaultFileBrowser: IDefaultFileBrowser,
139 | palette: ICommandPalette | null,
140 | translator: ITranslator | null
141 | ) => {
142 | const trans = (translator ?? nullTranslator).load('jupyterlab-quickopen');
143 | const commands: CommandRegistry = new CommandRegistry();
144 | const settings: ISettingRegistry.ISettings = await settingRegistry.load(
145 | extension.id
146 | );
147 | const widget: QuickOpenWidget = new QuickOpenWidget(
148 | defaultFileBrowser,
149 | settings.composite,
150 | {
151 | commands
152 | }
153 | );
154 |
155 | // Listen for path selection signals and show the selected files in the appropriate
156 | // editor/viewer
157 | widget.pathSelected.connect((sender: QuickOpenWidget, path: string) => {
158 | docManager.openOrReveal(PathExt.normalize(path));
159 | });
160 |
161 | // Listen for setting changes and apply them to the widget
162 | settings.changed.connect((settings: ISettingRegistry.ISettings) => {
163 | widget.settings = settings.composite;
164 | });
165 |
166 | // Add the quick open widget as a modal palette
167 | const modalPalette = new ModalCommandPalette({ commandPalette: widget });
168 | modalPalette.attach();
169 |
170 | // Add a command to activate the quickopen sidebar so that the user can find it in the command
171 | // palette, assign a hotkey, etc.
172 | const command = 'quickopen:activate';
173 | app.commands.addCommand(command, {
174 | label: trans.__('Quick Open'),
175 | execute: () => {
176 | modalPalette.activate();
177 | }
178 | });
179 | if (palette) {
180 | palette.addItem({ command, category: 'File Operations' });
181 | }
182 | }
183 | };
184 |
185 | export default extension;
186 |
--------------------------------------------------------------------------------
/style/base.css:
--------------------------------------------------------------------------------
1 | .jp-SearchIcon {
2 | background-image: var(--jp-icon-search);
3 | }
4 |
--------------------------------------------------------------------------------
/style/index.css:
--------------------------------------------------------------------------------
1 | @import url('base.css');
2 |
--------------------------------------------------------------------------------
/style/index.js:
--------------------------------------------------------------------------------
1 | import './base.css';
2 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "composite": true,
5 | "declaration": true,
6 | "esModuleInterop": true,
7 | "incremental": true,
8 | "jsx": "react",
9 | "module": "esnext",
10 | "moduleResolution": "node",
11 | "noEmitOnError": true,
12 | "noImplicitAny": true,
13 | "noUnusedLocals": true,
14 | "preserveWatchOutput": true,
15 | "resolveJsonModule": true,
16 | "outDir": "lib",
17 | "rootDir": "src",
18 | "strict": true,
19 | "strictNullChecks": true,
20 | "target": "ES2018"
21 | },
22 | "include": ["src/*"]
23 | }
24 |
--------------------------------------------------------------------------------