You should try hs-hide-level
with numeric prefix argument. The argument specifies the sub-level of the blocks to hide relative to the block you are in.
If you want to have some kind of current level within the whole buffer and you want to hide the next or the previous sub-level you can try the following code.
Paste that code into your init-file and re-start emacs. Afterwards you can use C-c @ > for hiding the next level and C-c @ < for hiding the previous level. There are also menu items in the Hide/Show
menu for that.
Note that this is a minimal implementation. An actual implementation could be much more refined.
Possible improvements:
- optionally detect the current level by the currently hidden parts of the buffer
- reduce
hs-current-level
appropriately when regions of the json buffer are killed
(require 'hideshow)
(defvar-local hs-current-level 1
"Currently hidden level of hideshow.")
(defvar-local hs-prev-level-active nil
"Deactivate `hs-hide-prev-level' when `hs-current-level' is 1.")
(defvar-local hs-next-level-active t
"Deactivate `hs-hide-next-level' when there are no hs overlays anymore.")
(defun hs-overlays-p (&optional ignore-comments)
"Return non-nil if there are still hs-overlays.
Ignore comments if IGNORE-COMMENTS is non-nil."
(let (ol)
(save-excursion
(goto-char (point-min))
(while (and (null (eobp))
(null (and (setq ol (hs-overlay-at (goto-char (next-overlay-change (point)))))
(or (null ignore-comments)
(null (eq (overlay-get ol 'hs) 'comment)))))))
(null (eobp)))))
(defun hs-hide-prev-level ()
"Hide level `hs-current-level'-1."
(interactive)
(save-excursion
(goto-char (point-min))
(setq hs-current-level (max (1- hs-current-level) 1))
(hs-hide-level hs-current-level)))
(defun hs-hide-next-level ()
"Hide level `hs-current-level'+1."
(interactive)
(save-excursion
(goto-char (point-min))
(setq hs-current-level (1+ hs-current-level))
(hs-hide-level hs-current-level)))
(define-key hs-minor-mode-map (kbd "C-c @ >") #'hs-hide-next-level)
(define-key hs-minor-mode-map (kbd "C-c @ <") #'hs-hide-prev-level)
(easy-menu-add-item hs-minor-mode-menu nil ["Hide previous level" hs-hide-prev-level (> hs-current-level 1)] "Toggle Hiding")
(easy-menu-add-item hs-minor-mode-menu nil ["Hide next level" hs-hide-next-level (hs-overlays-p t)] "Toggle Hiding")
Test-conditions:
emacs-version
: GNU Emacs 25.3.1 (x86_64-unknown-cygwin, GTK+ Version 3.22.20) of 2017-09-11
.json
-buffers are associated to java-mode
as major-mode
from cc-mode.el
shipping with emacs 25.3.1
hs-minor-mode
shipping with emacs 25.3.1
Testing the built-in functionality of hide/show:
Modified version of an example from http://json.org/example.html:
{"web-app": {
"servlet": [
{
"servlet-name": "cofaxCDS",
"servlet-class": "org.cofax.cds.CDSServlet",
"init-param": {
"additional sub-level": {
"item 1": "1",
"item 2": "2",
},
"configGlossary:installationAt": "Philadelphia, PA",
"configGlossary:adminEmail": "ksm@pobox.com"}},
{
"servlet-name": "cofaxEmail",
"servlet-class": "org.cofax.cds.EmailServlet",
"init-param": {
"mailHost": "mail1",
"mailHostOverride": "mail2"}},
{
"servlet-name": "cofaxAdmin",
"servlet-class": "org.cofax.cds.AdminServlet"},
{
"servlet-name": "fileServlet",
"servlet-class": "org.cofax.cds.FileServlet"},
{
"servlet-name": "cofaxTools",
"servlet-class": "org.cofax.cms.CofaxToolsServlet",
"init-param": {
"templatePath": "toolstemplates/",
"log": 1}}],
"servlet-mapping": {
"cofaxCDS": "/",
"cofaxEmail": "/cofaxutil/aemail/*"},
"taglib": {
"taglib-uri": "cofax.tld",
"taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
Hiding sub-levels:
Put point behind "web-app":
and press C-2 C-c @ C-l for hs-hide-level
with prefix-arg 2:
{"web-app": {
"servlet": [
{...},
{...},
{...},
{...},
{...}],
"servlet-mapping": {...},
"taglib": {...}}}
Revealing one more sub-level:
Keeping point position press C-3 C-c @ C-l:
{"web-app": {
"servlet": [
{
"servlet-name": "cofaxCDS",
"servlet-class": "org.cofax.cds.CDSServlet",
"init-param": {...}},
{
"servlet-name": "cofaxEmail",
"servlet-class": "org.cofax.cds.EmailServlet",
"init-param": {...}},
{
"servlet-name": "cofaxAdmin",
"servlet-class": "org.cofax.cds.AdminServlet"},
{
"servlet-name": "fileServlet",
"servlet-class": "org.cofax.cds.FileServlet"},
{
"servlet-name": "cofaxTools",
"servlet-class": "org.cofax.cms.CofaxToolsServlet",
"init-param": {...}}],
"servlet-mapping": {
"cofaxCDS": "/",
"cofaxEmail": "/cofaxutil/aemail/*"},
"taglib": {
"taglib-uri": "cofax.tld",
"taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
Revealing sub-levels in single blocks:
Put point behind the first "servlet-name":
and press C-2 C-c @ C-l:
{"web-app": {
"servlet": [
{
"servlet-name": "cofaxCDS",
"servlet-class": "org.cofax.cds.CDSServlet",
"init-param": {
"additional sub-level": {...},
"configGlossary:installationAt": "Philadelphia, PA",
"configGlossary:adminEmail": "ksm@pobox.com"}},
{
"servlet-name": "cofaxEmail",
"servlet-class": "org.cofax.cds.EmailServlet",
"init-param": {...}},
{
"servlet-name": "cofaxAdmin",
"servlet-class": "org.cofax.cds.AdminServlet"},
{
"servlet-name": "fileServlet",
"servlet-class": "org.cofax.cds.FileServlet"},
{
"servlet-name": "cofaxTools",
"servlet-class": "org.cofax.cms.CofaxToolsServlet",
"init-param": {...}}],
"servlet-mapping": {
"cofaxCDS": "/",
"cofaxEmail": "/cofaxutil/aemail/*"},
"taglib": {
"taglib-uri": "cofax.tld",
"taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
Testing the new hs-hide-prev-level
and hs-hide-next-level
:
At first application `hs-current-level` is 1.
If you put point anywhere in the buffer and press C-c @ > you get independent of the currently hidden blocks:
{"web-app": {
"servlet": [
{...},
{...},
{...},
{...},
{...}],
"servlet-mapping": {...},
"taglib": {...}}}
Next application of C-c @ > gives:
{"web-app": {
"servlet": [
{
"servlet-name": "cofaxCDS",
"servlet-class": "org.cofax.cds.CDSServlet",
"init-param": {...}},
{
"servlet-name": "cofaxEmail",
"servlet-class": "org.cofax.cds.EmailServlet",
"init-param": {...}},
{
"servlet-name": "cofaxAdmin",
"servlet-class": "org.cofax.cds.AdminServlet"},
{
"servlet-name": "fileServlet",
"servlet-class": "org.cofax.cds.FileServlet"},
{
"servlet-name": "cofaxTools",
"servlet-class": "org.cofax.cms.CofaxToolsServlet",
"init-param": {...}}],
"servlet-mapping": {
"cofaxCDS": "/",
"cofaxEmail": "/cofaxutil/aemail/*"},
"taglib": {
"taglib-uri": "cofax.tld",
"taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
Afterwards pressing C-c @ < gives the previous hs-state again.