Come usare "o" per aprire da dired / ibuffer in un altro frame


8

Ho due finestre aperte e divise verticalmente (frame singolo):

A) contiene il mio lavoro
B) contiene dired o ibuffer.

Vorrei poter accedere a un file / buffer nel riquadro B e premere "o" per aprirlo nel riquadro A. È possibile? In questo momento emacs sta creando un nuovo riquadro nella parte inferiore del riquadro A per aprire il file.

modifica: secondo la lista degli utenti, il comportamento sopra descritto si verificherà quando il frame è grande. Questo sembra essere il caso per me perché ora che sono a casa (non su un monitor esterno, un frame più piccolo) emacs si sta comportando come desidero. La domanda ora diventa: posso impedire a emacs di aprire una nuova finestra quando il frame corrente è grande?


1
Benvenuto nel forum beta di Emacs. Come parte del gergo / gergo di Emacs, usiamo la parola windowper fare riferimento a un quadrante di buffer all'interno dello stesso frame. A frameè considerato l'intero gattino-kaboodle, che può avere molte finestre al suo interno. Emacs può generare più frame, con ogni frame contenente più finestre.
— elenco delle leggi

grazie per il chiarimento! Sono un utente di Emacs da molto tempo, ma non ho mai compreso appieno la terminologia.
— Robert,

Risposte:


6

Ecco quattro (4) display-bufferfamiglie di funzioni personalizzate di esempio che possono essere personalizzate per soddisfare le esigenze specifiche di un utente - sopra ; sotto ; a sinistra ; a destra - e qui ci sono quattro (4) interactivefunzioni per visualizzare il file o la directory della riga corrente di un dired-modebuffer. Esistono solo tre condizioni: (a) se esiste già una finestra che mostra il buffer di destinazione, quindi sceglierlo; (b) se è disponibile una finestra nella direzione desiderata, quindi usarla; (c) il punto di partenza è creare una nuova finestra nella direzione desiderata se le altre condizioni non sono soddisfatte.

Uso:

M-x dired-display-above

M-x dired-display-below

M-x dired-display-left

M-x dired-display-right

Ci sono così tante combinazioni di tasti già integrate dired-modee dired+che non oso tentare di inventare la mia. L'utente è libero di scegliere le proprie scorciatoie da tastiera, che vanno oltre lo scopo di questo esempio limitato.

L'utente è libero di aggiungere condizioni aggiuntive alla display-bufferfamiglia di funzioni di esempio per gestire più situazioni, ad esempio più finestre di una coppia.

(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: Ecco un'implementazione leggermente più sofisticata / divertente del concetto sopra, che offre all'utente la possibilità di utilizzarlo in modo non interattivo o interattivo ; ad es. M-x dired-display-buffer- dove all'utente verrà richiesto di scegliere una directory se non passa il mouse sopra un file dired-modee di scegliere una direzione di visualizzazione (sinistra, destra, sopra, sotto).

(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 questo è perfetto. Qualcuno può aiutarmi con semplice hydra per dired-mode-map, associato a oe poi hjklper display-sopra / sotto / sinistra / destra?
— iLemming

oh penso di averlo capito: (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

Piccola cosa sull'approccio: non passa alla finestra appena creata. Non riesco a capire come forzarlo.
— iLemming

2
@Agzam - La funzione select-windowpuò essere utilizzata alla fine di ogni my-display-buffer-...funzione. Come puoi vedere, il risultato / valore che viene lanciato alla fine sull'ultima riga è window. Se non è necessario il risultato / valore da utilizzare in combinazione con un'altra funzione, poi basta avvolgere il window sul all'ultima riga con questo: (select-window window). Fallo con tutte e quattro le (4) funzioni - ovvero my-display-buffer-below,; my-display-buffer-above; my-display-buffer-left; e my-display-buffer-right.
— elenco delle leggi

3

La tua domanda non è chiara e quindi rischia di essere chiusa. Hai due frame o un singolo frame con due finestre Emacs? Qualunque cosa siano, se ce ne sono due, ognuno di essi è diviso verticalmente? E cosa intendi per "divisione verticale"? Cosa intendi per "riquadro"? Cosa intendi con "esso", in "aprilo nel riquadro A"?

Un'ipotesi selvaggia è che hai un singolo frame Emacs che è diviso in due finestre Emacs, A e B, con la finestra A sopra la finestra B, la finestra B è selezionata e la finestra B mostra un buffer Dired.

oè associato per impostazione predefinita a dired-find-file-other-window. Se quanto sopra supposizione è corretto quindi osu un nome di file in B dovrebbe aprire in A. Questo è quello che vedo quando si avvia Emacs senza un file init: emacs -Q. Non lo vedi?

Se questo non è lo scenario, descrivi chiaramente cosa stai facendo, passo dopo passo, a partire da emacs -Q.


2
Dipende dalle dimensioni del frame: un frame grande comporterà il comportamento descritto dall'OP; invece, una cornice più piccola comporterà il comportamento descritto da Drew.
— elenco delle leggi

elenco di leggi Penso che sia esattamente ciò che sta accadendo. Quando è collegato al mio monitor esterno con una cornice di grandi dimensioni ciò che ho descritto accade, ma ora che sono a casa sul display del mio laptop più piccolo, mi viene chiesto come desidero: c'è un modo per costringerlo a non aprire un'altra finestra?
— Robert,

Ciao Drew, scusate, non sono completamente al passo con il gergo di emacs per quanto riguarda le differenze tra un frame e una finestra. Quello che intendevo nella mia domanda originale (se ora capisco correttamente le finestre e i frame) è che ho un singolo frame emacs e due finestre emacs affiancate (verticalmente Cx 3). Tutto funziona come previsto quando sono sul mio laptop e la cornice è piccola, ma come indicato dalla lista della legge quando la cornice è grande ciò che descrivo accade.
— Robert,

Sì, è possibile. Tuttavia, un'impostazione generale della display-bufferfamiglia di variabili influenzerà altre situazioni non ancora previste. Puoi personalizzare il display-buffer-alist, il che è un po 'confuso anche per gli utenti Emacs esperti. Ci sono variabili che controllano quando dividere finestre e dimensioni minime di finestre e l'elenco potrebbe continuare all'infinito. Per contenere l'epidemia, potresti consigliarti dired-find-file-other-windowcon una versione del limite display-buffer-alist, ma lascerò la risposta a un altro partecipante al forum. Esistono diverse soluzioni. :)
— elenco delle leggi del

1

NOTA : le seguenti variabili sono globali , il che significa che influenzeranno anche altre funzioni dired-find-file-other-window. L'utente potrebbe voler consigliare la funzione in questione in modo da non influenzare globalmente altre funzioni. [Tuttavia, questo autore lascerà questa opzione a un altro partecipante al forum.] In alternativa, c'è un'altra risposta che questo autore ha pubblicato contenente funzioni personalizzate che possono essere utilizzate in modo da non influenzare nient'altro.


La variabile split-width-thresholdha una stringa doc che afferma:

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.

Impostando quanto segue nel .emacsfile si otterrà l'effetto desiderato. L'utente può anche impostare il valore su un numero più alto. Il valore predefinito è 160

(setq split-width-threshold nil)

Ecco un link alla sezione pertinente del manuale:

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


Vedi anche la variabile correlata split-height-threshold, che ha un valore predefinito di 80

La stringa di documenti afferma:

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.

In realtà ha funzionato abbastanza bene! Ora, se inizia qualcosa di divertente, almeno so dove cercare. Grazie ancora!
— Robert,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.