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.