Comment utiliser «o» pour ouvrir depuis dired / ibuffer dans un autre cadre


8

J'ai deux fenêtres ouvertes et divisées verticalement (un seul cadre):

A) contient mon travail
B) contient soit dired soit ibuffer.

Je voudrais pouvoir naviguer vers un fichier / tampon dans le volet B et appuyer sur "o" pour l'ouvrir dans le volet A. Est-ce possible? En ce moment, emacs crée un nouveau volet dans la partie inférieure du volet A pour ouvrir le fichier.

modifier: selon la loi de l'utilisateur, le comportement décrit ci-dessus se produit lorsque le cadre est grand. Cela semble être le cas pour moi car maintenant que je suis à la maison (pas sur un moniteur externe, un cadre plus petit), emacs se comporte comme je le souhaite. La question devient maintenant: puis-je empêcher emacs d'ouvrir une nouvelle fenêtre lorsque le cadre actuel est grand?


1
Bienvenue sur le forum bêta d'Emacs. Dans le jargon / jargon Emacs, nous utilisons le mot windowpour désigner un quadrant tampon dans le même frame. A frameest considéré comme l'ensemble du chaton-kaboodle, qui peut contenir de nombreuses fenêtres. Emacs peut générer plusieurs images, chaque image contenant plusieurs fenêtres.
lawlist

Merci pour la clarification! Je suis un utilisateur emacs de longue date mais je n'ai jamais complètement compris la terminologie.
Robert

Réponses:


6

Voici quatre (4) exemples de display-bufferfamilles de fonctions personnalisées qui peuvent être personnalisées pour répondre aux besoins particuliers d'un utilisateur - ci - dessus ; ci-dessous ; gauche ; à droite - et voici quatre (4) interactivefonctions pour afficher le fichier ou le répertoire de la ligne courante d'un dired-modetampon. Il n'y a que trois conditions: (a) s'il existe déjà une fenêtre affichant le tampon cible, choisissez-le; (b) s'il existe une fenêtre disponible dans la direction souhaitée, alors utilisez-la; (c) le fourre-tout est de créer une nouvelle fenêtre dans la direction souhaitée si les autres conditions ne sont pas remplies.

Usage:

M-x dired-display-above

M-x dired-display-below

M-x dired-display-left

M-x dired-display-right

Il y a tellement de raccourcis clavier déjà intégrés à dired-modeet dired+que je n'ose pas essayer de créer le mien. L'utilisateur est libre de choisir ses propres raccourcis clavier, ce qui dépasse le cadre de cet exemple limité.

L'utilisateur est libre d'ajouter des conditions supplémentaires à l'exemple de display-bufferfamille de fonctions pour gérer plus de situations - par exemple, plus de fenêtres qu'un couple.

(defun my-display-buffer-below (buffer alist)
"Doc-string."
  (let (
      (window
        (cond
          ((get-buffer-window buffer (selected-frame)))
          ((window-in-direction 'below))
          (t
            (split-window (selected-window) nil 'below)))))
    (window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
    window))

(defun my-display-buffer-above (buffer alist)
"Doc-string."
  (let (
      (window
        (cond
          ((get-buffer-window buffer (selected-frame)))
          ((window-in-direction 'above))
          (t
            (split-window (selected-window) nil 'above)))))
    (window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
    window))

(defun my-display-buffer-left (buffer alist)
"Doc-string."
  (let (
      (window
        (cond
          ((get-buffer-window buffer (selected-frame)))
          ((window-in-direction 'left))
          (t
            (split-window (selected-window) nil 'left)))))
    (window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
    window))

(defun my-display-buffer-right (buffer alist)
"Doc-string."
  (let (
      (window
        (cond
          ((get-buffer-window buffer (selected-frame)))
          ((window-in-direction 'right))
          (t
            (split-window (selected-window) nil 'right)))))
    (window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
    window))

(defun dired-display-above ()
"Doc-string."
(interactive)
  (let* (
      (file-or-dir (dired-get-file-for-visit))
      (buffer (find-file-noselect file-or-dir)))
    (my-display-buffer-above buffer nil)))

(defun dired-display-below ()
"Doc-string."
(interactive)
  (let* (
      (file-or-dir (dired-get-file-for-visit))
      (buffer (find-file-noselect file-or-dir)))
    (my-display-buffer-below buffer nil)))

(defun dired-display-left ()
"Doc-string."
(interactive)
  (let* (
      (file-or-dir (dired-get-file-for-visit))
      (buffer (find-file-noselect file-or-dir)))
    (my-display-buffer-left buffer nil)))

(defun dired-display-right ()
"Doc-string."
(interactive)
  (let* (
      (file-or-dir (dired-get-file-for-visit))
      (buffer (find-file-noselect file-or-dir)))
    (my-display-buffer-right buffer nil)))

EDIT: Voici une implémentation légèrement plus sophistiquée / amusante du concept ci-dessus, qui donne à l'utilisateur la possibilité de l'utiliser de manière non interactive ou interactive ; par exemple, M-x dired-display-buffer- où l'utilisateur sera invité à choisir un répertoire s'il ne survole pas un fichier dans dired-mode, et à choisir une direction d'affichage (gauche, droite, dessus, dessous).

(defun my-display-buffer (buffer-or-name alist direction &optional size pixelwise)
"BUFFER:  The buffer that will be displayed.
ALIST:  See the doc-string of `display-buffer' for more information.
DIRECTION:  Must use one of these symbols:  'left 'right 'below 'above
SIZE:  See the doc-string for `split-window'.
PIXELWISE:  See the doc-string for `split-window'.
There are three possibilities:
-  (1) If a window on the frame already displays the target buffer,
then just reuse the same window.
-  (2) If there is already a window in the specified direction in relation
to the selected window, then display the target buffer in said window.
-  (3) If there is no window in the specified direction, then create one
in that direction and display the target buffer in said window."
  (let* ((buffer
           (if (bufferp buffer-or-name)
             buffer-or-name
             (get-buffer buffer-or-name)))
         (window
           (cond
             ((get-buffer-window buffer (selected-frame)))
             ((window-in-direction direction))
             (t
               (split-window (selected-window) size direction pixelwise)))))
    (window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
    window))

(defun dired-display-buffer (&optional direction alist)
"Display a dired-mode buffer or a file underneath point in a dired-mode buffer."
(interactive)
  (let* ((file-or-dir (or (and (eq major-mode 'dired-mode) (dired-get-file-for-visit))
                               (read-directory-name "Directory:  ")))
         (buffer (find-file-noselect file-or-dir))
         (direction
           (if direction
             direction
             (let ((char (read-char-exclusive (concat
                      "["
                      (propertize "l" 'face '(:foreground "red"))
                      "]"
                      (propertize "eft" 'face '(:foreground "blue"))
                      " | ["
                      (propertize "r" 'face '(:foreground "red"))
                      "]"
                      (propertize "ight" 'face '(:foreground "blue"))
                      " | ["
                      (propertize "a" 'face '(:foreground "red"))
                      "]"
                      (propertize "bove" 'face '(:foreground "blue"))
                      " | ["
                      (propertize "b" 'face '(:foreground "red"))
                      "]"
                      (propertize "elow" 'face '(:foreground "blue"))))))
                (cond
                  ((eq char ?l)
                    'left)
                  ((eq char ?r)
                    'right)
                  ((eq char ?a)
                    'above)
                  ((eq char ?b)
                    'below)
                  ;;; FIXME:  @lawlist may add a loop similar to `org-capture'
                  ;;; whereby a new `read-char-exclusive' will be initiated if
                  ;;; a user did not initially choose a valid option (l/r/a/b).
                  (t
                    (let ((debug-on-quit nil)
                          (msg (concat "dired-display-buffer:  "
                                       "You did not select l/r/a/b "
                                       "-- exiting.")))
                      (signal 'quit `(,msg)))))))))
    (my-display-buffer buffer alist direction)))

oh c'est parfait. Quelqu'un peut-il m'aider avec de l'hydre simple pour dired-mode-map, lié à opuis hjklpour l'affichage au-dessus / en dessous / à gauche / à droite?
iLemming

oh je pense que je l'ai: (defhydra dired-open (dired-mode-map "O" :exit t) "dired-open" ("j" dired-display-below "below") ("k" dired-display-above "above") ("h" dired-display-left "left") ("l" dired-display-right "left"))
iLemming

Petite chose à propos de l'approche - elle ne saute pas à la fenêtre nouvellement créée. Je ne sais pas comment le forcer.
iLemming

2
@Agzam - La fonction select-windowpeut être utilisée à la fin de chaque my-display-buffer-...fonction. Comme vous pouvez le voir, le résultat / valeur qui est jeté à la fin sur la toute dernière ligne est window. Si vous n'avez pas besoin du résultat / valeur à utiliser conjointement avec une autre fonction, puis juste envelopper la window sur la dernière ligne avec ceci: (select-window window). Faites cela avec les quatre (4) fonctions - c'est-à-dire my-display-buffer-below; my-display-buffer-above; my-display-buffer-left; et my-display-buffer-right.
lawlist

3

Votre question n'est pas claire et risque donc d'être fermée. Avez-vous deux cadres ou un seul cadre avec deux fenêtres Emacs? Quels qu'ils soient, s'il y en a deux, chacun d'eux est-il divisé verticalement? Et que voulez-vous dire par "diviser verticalement"? Qu'entendez-vous par un "volet"? Que voulez-vous dire par "il", dans "l'ouvrir dans le volet A"?

Une supposition sauvage est que vous avez un seul cadre Emacs qui est divisé en deux fenêtres Emacs, A et B, avec la fenêtre A au-dessus de la fenêtre B, la fenêtre B est sélectionnée et la fenêtre B affiche un tampon fatigué.

oest lié par défaut à dired-find-file-other-window. Si ce qui précède est correcte conjecture sauvage puis osur un nom de fichier B devrait ouvrir en A. C'est ce que je vois lors du démarrage Emacs sans fichier init: emacs -Q. Ne voyez-vous pas cela?

Si ce n'est pas le scénario, veuillez décrire clairement ce que vous faites, étape par étape, en commençant par emacs -Q.


2
Cela dépend de la taille de la trame - une grande trame entraînera le comportement décrit par l'OP; tandis qu'un cadre plus petit entraînera le comportement décrit par Drew.
lawlist

je pense que c'est exactement ce qui se passe. Lorsqu'il est attaché à mon moniteur externe avec un grand cadre, ce que j'ai décrit se produit, mais maintenant que je suis à la maison sur mon petit écran d'ordinateur portable, il me demande - existe-t-il un moyen de le forcer à ne pas ouvrir une autre fenêtre?
Robert

Salut Drew désolé, je ne suis pas complètement au courant du jargon emacs en ce qui concerne les différences entre un cadre et une fenêtre. Ce que je voulais dire dans ma question d'origine (si je comprends maintenant correctement les fenêtres et les cadres), c'est que j'ai un seul cadre emacs et deux fenêtres emacs côte à côte (verticalement Cx 3). Tout fonctionne comme prévu lorsque je suis sur mon ordinateur portable et que le cadre est petit, mais comme l'a souligné Lawlist lorsque le cadre est grand, ce que je décris se produit.
Robert

Oui c'est possible. Cependant, un cadre général de la display-bufferfamille de variables affectera d'autres situations non encore prévues. Vous pouvez personnaliser le display-buffer-alist, ce qui est quelque peu déroutant même pour les utilisateurs expérimentés d'Emacs. Il existe des variables qui contrôlent quand diviser les fenêtres et les tailles minimales des fenêtres, et la liste s'allonge encore et encore. Pour contenir l'épidémie, vous pouvez conseiller dired-find-file-other-windowune version reliée de la display-buffer-alist, mais je laisserai cette réponse à un autre participant au forum. Il existe différentes solutions. :)
lawlist

1

REMARQUE : les variables suivantes sont globales , ce qui signifie qu'elles affecteront d'autres fonctions en plus dired-find-file-other-window. L'utilisateur peut souhaiter conseiller la fonction en question afin de ne pas affecter globalement les autres fonctions. [Cependant, cet auteur laissera cette option à un autre participant au forum.] Alternativement, il y a une autre réponse que cet auteur a postée, contenant des fonctions personnalisées qui peuvent être utilisées pour ne rien affecter d'autre.


La variable split-width-thresholda une doc-string qui indique:

Minimum width for splitting windows sensibly.
If this is an integer, ‘split-window-sensibly’ may split a window
horizontally only if it has at least this many columns.  If this
is nil, ‘split-window-sensibly’ is not allowed to split a window
horizontally.

Le réglage de ce qui suit dans le .emacsfichier produira l'effet souhaité. L'utilisateur peut également définir la valeur sur un nombre supérieur. La valeur par défaut est 160

(setq split-width-threshold nil)

Voici un lien vers la section pertinente du manuel:

https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Choice.html


Voir aussi la variable associée split-height-threshold, qui a une valeur par défaut de 80

La doc-string indique:

Minimum height for splitting windows sensibly.
If this is an integer, `split-window-sensibly' may split a window
vertically only if it has at least this many lines.  If this is
nil, `split-window-sensibly' is not allowed to split a window
vertically.  If, however, a window is the only window on its
frame, `split-window-sensibly' may split it vertically
disregarding the value of this variable.

Cela a plutôt bien fonctionné! Maintenant, si quelque chose de drôle commence à se produire, je sais au moins où chercher. Merci encore!
Robert
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.