Commits

seanmcl committed 5ce591f

window selection

Comments (0)

Files changed (5)

+
+changes
+=========
+
+- There is a big change regarding window behavior.
+
+  The following variables were removed
+     Omake.show-buffer-for-next-error-in
+     Omake.set-standard-windows
+     Omake.use-display-buffer
+
+  They were replaced by
+     Omake.split-window-horizontally
+     Omake.show-error-buffer-in-top-or-left-window
+
+  See the info documentation for the new behavior.  This change was done
+  as a uniform method for supporting the various different ways of using
+  dedicated windows vs. automatic window selection.
+
+  Non-experts should not have to do anything (though they might want to
+  remove the variables that are no longer used from their .emacs.)
+
+--------------------------------------------------------------------------------
 
 new stuff
 =========
      setting jane-highlight-whitespace-style.
    * trailing whitespace is cleaned up on file save, only in certain modes
       (c-mode tuareg-mode)
- 
+
 bug fixes
 =========
 

elisp-for-ocaml-programmers.el

 ;;                  (funcall f ctr b)
 ;;                  (setq ctr (+ ctr 1))) l)))
 ;;
-;; This definition of List.iteri fails.  In (List.iteri g l) 
+;; This definition of List.iteri fails.  In (List.iteri g l)
 ;; `f' is bound to g in the beginning of the body of List.iteri, but when List.iter
 ;; is called, f gets rebound to (lambda (b) ...).  Thus the funcall fails
-;; because it expects only 1 argument.  
+;; because it expects only 1 argument.
 ;;
 ;; For example
 ;;
   `(let ((inhibit-quit t))
      ,@form))
 
+(defun nequal (x y) (not (equal x y)))
+
 
 ;; Lexical defun and let
 
   "Lexical defun.  Not for use with interactive functions"
   (declare (indent defun))
   (let* (;; remove &optional and &rest
-         (args (remove-if 
-                (lambda (s) (equal (substring (symbol-name s) 0 1) "&")) 
+         (args (remove-if
+                (lambda (s) (equal (substring (symbol-name s) 0 1) "&"))
                 arglist))
          (args (mapcar (lambda (arg) (list arg arg)) args))
          ;; put the doc string before the lexical-let
-         (doc_body (if (and (> (length body) 1) 
+         (doc_body (if (and (> (length body) 1)
                             (stringp (car body)))
                        `(,(car body) . ,(cdr body))
                      `(nil . ,body)))
          (body (cdr doc_body)))
     `(defun ,name ,arglist
        ,(if doc doc)
-       (lexical-let 
+       (lexical-let
            ,args
          ,@body))))
 ;; (macroexpand '(defunl f (x y) (+ x y)))
     &or symbolp (gate symbolp &optional form))
    body))
 
-(font-lock-add-keywords 
- 'emacs-lisp-mode 
+(font-lock-add-keywords
+ 'emacs-lisp-mode
  '(("\\<\\(defunl\\)" 1 font-lock-keyword-face)
    ("\\<\\(letl\\*?\\)" 1 font-lock-keyword-face))
  t)
 
 (defunl List.mapi (f l)
   (letl ((i 0))
-    (mapcar (lambda (x) 
+    (mapcar (lambda (x)
               (letl ((y (funcall f i x)))
                 (setq i (1+ i))
                 y)) l)))
   (let ((from (if from from 0)))
     (if (< n from) nil (List.upto-aux n from nil))))
 
-(Jane.test (List.upto 3) '(0 1 2 3)) 
-(Jane.test (List.upto 3 2) '(2 3)) 
+(Jane.test (List.upto 3) '(0 1 2 3))
+(Jane.test (List.upto 3 2) '(2 3))
 
 (defunl List.concat-map (f l)
   (apply 'append (List.map f l)))
               (cons nil nil) l))
 (Jane.test (List.partition (lambda (x) (< x 4)) '(1 2 3 4 5)) '((1 2 3) . (4 5)))
 
-(defunl List.inter (l1 l2) 
+(defunl List.inter (l1 l2)
   (List.filter (lambda (x) (List.mem l2 x)) l1))
 (Jane.test (List.inter '(1 2 3) '(2 3 4)) '(2 3))
 (Jane.test (List.inter '(1 2 3) '()) '())
   (let ((w (if w w (selected-window))))
     (get-window-with-predicate (lambda (w1) (not (equal w w1))) nil t)))
 
+(defun Window.all-visible ()
+  "Return all visible windows in all visible frames."
+  (apply 'append (mapcar (lambda (f) (window-list f "no-mini")) (frame-list))))
+;; (Window.all-visible)
+
 
 ;; Timers
 
 (defun Emacs.insert-object (x) (insert (prin1-to-string x)))
 ;; (Emacs.insert-object "sean")
 
+(defun File.byte-compile-check ()
+  (interactive)
+  (let ((file (read-file-name "File: ")))
+    (byte-compile-file file)
+    (message "removing compiled file")
+    (Shell.rm (concat file "c"))))
+
 
 ;; Hg
 

info/omake-server.texi

 In the case that the frame F contains exactly two windows, one showing
 the error buffer and the other showing the code buffer, and if no
 dedicated windows exist, then arrange the windows according to the
-variable Omake.show-error-buffer-in-top-or-left-window as follows.
+variable @code{Omake.show-error-buffer-in-top-or-left-window} as follows.
 
 @subsection Errors buffer
 
   :group 'omake
   :type 'string)
 
-(defcustom Omake.show-buffer-for-next-error-in 'dedicated-code-window
-  "Either 'dedicated-code-window or 'selected-window"
-  :group 'omake
-  :type 'symbol)
-;; (setq Omake.show-buffer-for-next-error-in 'selected-window)
-
-(defcustom Omake.set-standard-windows nil
-  "If t, when you run `Omake.compile' in a frame, it
-will split the frame horizontally, show your code on the left window and the
-errors on the right window."
-  :group 'omake
-  :type 'boolean)
-;; (setq Omake.set-standard-windows t)
-
-(defcustom Omake.use-display-buffer nil
-  "If t, use display-buffer to show the code and error buffer.")
-
 (defcustom Omake.prompt-before-killing-project t
   "If t, prompt y/n before killing a project"
   :group 'omake
   :type 'boolean)
 ;; (setq Omake.prompt-before-killing-project nil)
 
+(defcustom Omake.split-window-horizontally t
+  "See the info documentation for when this variable takes effect."
+  :group 'omake
+  :type 'boolean)
+;; (setq Omake.split-window-horizontally t)
+;; (setq Omake.split-window-horizontally nil)
+
+(defcustom Omake.show-error-buffer-in-top-or-left-window nil
+  "See the info documentation for what this is and when it takes effect."
+  :group 'omake
+  :type 'boolean)
+;; (setq Omake.show-error-buffer-in-top-or-left-window t)
+;; (setq Omake.show-error-buffer-in-top-or-left-window nil)
+
 ;;============================================================================;;
 ;; Faces                                                                      ;;
 ;;============================================================================;;
 ;; If there has been a version change upon loading this library,
 ;; kill the o-server.
 (when (and (boundp 'Omake.version)
-           (not (equal Omake.pre-version Omake.version))
+           (nequal Omake.pre-version Omake.version)
            (Omake.Server.running-p))
   (let ((res (y-or-n-p
     "Omake was updated.  Kill your server and reload? ")))
 (defconst Omake.version Omake.pre-version)
 
 ;;============================================================================;;
-;; Windows                                                                    ;;
+;; Windows and frames
 ;;============================================================================;;
 
-;; The user can set dedicated windows for
-;;   - the error buffer
-;;   - the code buffer
+(defvar Omake.Window.Error nil)
+(defvar Omake.Window.Code nil)
+(defvar Omake.Frame.Error nil)
+(defvar Omake.Frame.Code nil)
 
-;; type window = Error | Code
+(defun Omake.Window.clear-dedicated ()
+  (setq Omake.Window.Error nil)
+  (setq Omake.Window.Code nil))
 
-(defstruct
-  (Omake.window-kind
-   (:constructor nil)
-   (:constructor Omake.Window.Error (&aux (data 1)))
-   (:constructor Omake.Window.Code  (&aux (data 2))))
-  (data nil :read-only t))
+(defmacro Omake.Window.check (w)
+  `(and ,w
+       (not (window-live-p ,w))
+       (setq ,w nil)))
+;; (macroexpand '(Omake.Window.check Omake.Window.Error))
 
-(defconst Omake.Window.Error (Omake.Window.Error))
-(defconst Omake.Window.Code  (Omake.Window.Code))
+(defmacro Omake.Frame.check (f)
+  `(and ,f
+        (or (not (frame-live-p ,f))
+            (not (frame-visible-p ,f)))
+        (setq ,f nil)))
+;; (macroexpand '(Omake.Frame.check Omake.Frame.Error))
+;; (frame-visible-p Omake.Frame.Error)
 
-(defvar Omake.Window.window-table (make-hash-table :test 'equal))
+(defun Omake.Window.kindp (kind)
+  (case kind
+    ((code error) t)
+    (t nil)))
+;; (Omake.Window.kindp 'code)
+;; (Omake.Window.kindp 'error)
+;; (Omake.Window.kindp 'abc)
+;; (Omake.Window.kindp nil)
 
-(defun Omake.Window.set (kind w)
-  (assert (Omake.window-kind-p kind))
-  (assert (window-live-p w))
-  (puthash kind w Omake.Window.window-table))
+(defun Omake.check-dedicated ()
+  (Omake.Window.check Omake.Window.Error)
+  (Omake.Window.check Omake.Window.Code)
+  (Omake.Frame.check Omake.Frame.Error)
+  (Omake.Frame.check Omake.Frame.Code)
+  (assert (or (null Omake.Window.Code)
+              (null Omake.Window.Error)
+              (nequal Omake.Window.Code Omake.Window.Error))))
 
 (defun Omake.Window.get (kind)
-  "Get an omake window.  Return the current window if none is set."
-  (assert (Omake.window-kind-p kind))
-  (if (and (equal kind Omake.Window.Code)
-           ;; CR sweeks: Seems like this should be a [case] expression.
-           (equal Omake.show-buffer-for-next-error-in 'selected-window))
-      (selected-window)
-    (let* ((w (gethash kind Omake.Window.window-table))
-           (ok (and w (window-live-p w)))
-           (w (if ok w (selected-window))))
-      (unless ok (Omake.Window.set kind w))
-      w)))
+  (assert (Omake.Window.kindp kind))
+  (case kind
+    ('error Omake.Window.Error)
+    ('code Omake.Window.Code)
+    (t (error "Impossible"))))
 
-(defun Omake.Window.guess-error-window ()
-  "Try to guess a good window for the error buffer"
-  (let ((w (selected-window))
-        (w1 (next-window t)))
-    (if (equal w w1) (split-window-horizontally) w1)))
+(defun Omake.Frame.get (kind)
+  (assert (Omake.Window.kindp kind))
+  (case kind
+    ('error Omake.Frame.Error)
+    ('code Omake.Frame.Code)
+    (t (error "Impossible"))))
+
+(defun Omake.Frame.split ()
+  ;; If we're splitting, there's a single frame with a single window.  If it's
+  ;; dedicated, we have no hope of maintaining it
+  (Omake.Window.clear-dedicated)
+  (let ((right (if Omake.split-window-horizontally
+                   (split-window-horizontally)
+                 (split-window-vertically)))
+        (left (selected-window)))
+    (if Omake.show-error-buffer-in-top-or-left-window
+        (cons right left)
+      (cons left right))))
+
+(defun Omake.choose-frame-and-maybe-window (kind buffer other-dedicated-window)
+  (assert (Omake.Window.kindp kind))
+  (let ((dw (Omake.Window.get kind))
+        (df (Omake.Frame.get kind)))
+    (if dw (cons (window-frame dw) dw)
+      (let* ((try-windows
+              (if df (window-list df) (Window.all-visible)))
+             (or-else-frame
+              (if df df (window-frame (selected-window))))
+             (final-window
+              (List.find
+               (lambda (w)
+                 (and
+                  buffer
+                  (equal (window-buffer w) buffer)
+                  (or (null other-dedicated-window)
+                      (nequal w other-dedicated-window))))
+               try-windows)))
+        (if final-window
+            (cons (window-frame final-window) final-window)
+          (cons or-else-frame nil))))))
+
+(defun Omake.obeys-dedicated (kind w)
+  (assert (Omake.Window.kindp kind))
+  (assert (window-live-p w))
+  (let ((dw (Omake.Window.get kind))
+        (df (Omake.Frame.get kind)))
+    (cond
+     (dw (equal dw w))
+     (df (equal df (window-frame w)))
+     (t t))))
+
+(defun Omake.choose-windows (id code-buffer-opt)
+  "Return (code-window . error-window) and set the code and error buffers"
+  (assert (Omake.id-p id))
+  (assert (or (null code-buffer-opt) (bufferp code-buffer-opt)))
+  (Omake.check-dedicated)
+  (let* (;; If there's no code buffer, grab an arbitrary buffer and use
+         ;; that as we go through the code.  Just don't set the code buffer
+         ;; in this case.
+         (model (Omake.Model.get id))
+         (error-buffer (Omake.model-error-buffer model))
+         (_ (assert (nequal code-buffer-opt error-buffer)))
+         (code (Omake.choose-frame-and-maybe-window
+                'code code-buffer-opt Omake.Window.Error))
+         (code-frame (car code))
+         (code-window (cdr code))
+         (err (Omake.choose-frame-and-maybe-window
+               'error error-buffer Omake.Window.Code))
+         (error-frame (car err))
+         (error-window (cdr err))
+         (_ (assert code-frame))
+         (_ (assert error-frame))
+         (or-selected (lambda (w f) (if w w (frame-selected-window f))))
+         (choice
+          (if (equal code-frame error-frame)
+              (let* ((frame code-frame)
+                     (sw (frame-selected-window frame))
+                     (windows (window-list frame))
+                     (unselected-ws (remove-if-not (lambda (w) (nequal w sw)) windows)))
+                (if (null unselected-ws) (Omake.Frame.split)
+                  (let* ((lru (when unselected-ws (car unselected-ws)))
+                         ;; Can't get lru from an arbitrary list of windows without digging into C
+                         (other-than (lambda (w) (if (equal w sw) lru sw))))
+                    (cond
+                     ((and code-window error-window) (cons code-window error-window))
+                     (code-window (cons code-window (funcall other-than code-window)))
+                     (error-window (cons (funcall other-than error-window) error-window))
+                     (t (cons sw lru))))))
+            ;; else
+            (cons (funcall or-selected code-window code-frame)
+                  (funcall or-selected error-window error-frame))))
+         (code (car choice))
+         (err (cdr choice)))
+    (assert (nequal code err))
+    (assert (Omake.obeys-dedicated 'code code))
+    (assert (Omake.obeys-dedicated 'error err))
+    choice))
 
 ;;============================================================================;;
 ;; Progress bar                                                               ;;
                  (string-match "[.~a-zA-Z0-9/_-]*[.a-zA-Z0-9~_-]" path)
                  (match-string 0 path))))
     (equal path legal)))
-;; (Omake.Path.ok "/home/sweeks/live/107.15.00/live/lib")
-;; (Omake.Path.ok "/home/sweeks/live/107.15.00/live/lib/aSet.ml")
-;; (Omake.Path.ok "/mnt/local/sda1/smclaughlin/elisp/dev/omake-mode")
-;; (Omake.Path.ok "/mnt/local.a.b.c/sda1/smclaughlin/elisp/dev/omake-mode")
-;; (Omake.Path.ok "~/gord-test")
+
+(progn
+  (Jane.test (Omake.Path.ok "/home/sweeks/live/107.15.00/live/lib") t)
+  (Jane.test (Omake.Path.ok "/home/sweeks/live/107.15.00/live/lib/aSet.ml") t)
+  (Jane.test (Omake.Path.ok "/mnt/local/sda1/smclaughlin/elisp/dev/omake-mode") t)
+  (Jane.test (Omake.Path.ok "/mnt/local.a.b.c/sda1/smclaughlin/elisp/dev/omake-mode") t)
+  (Jane.test (Omake.Path.ok "~/gord-test") t))
 
 (defun Omake.Path.omakeroot-dir (path)
   "Get the full, unaliased path to the OMakeroot file above the given path.
 
 (defun Omake.Error.show (e)
   (assert (Omake.error-p e))
-  (let* ((file (Omake.Error.file-path e))
-         (_
-          (if (not Omake.use-display-buffer)
-              (select-window (Omake.Window.get Omake.Window.Code))
-              (when
-                  (eq (current-buffer)
-                   (Omake.model-error-buffer (Omake.Model.current)))
-                (select-window (display-buffer
-                                (or (get-file-buffer file)
-                                    (create-file-buffer file)))))))
-         ;; At this point, the selected window is where we want to show the error.
-         (_ (find-file file))
+  (let* ((id (Omake.error-id e))
+         (model (Omake.Model.get id))
+         (error-buffer (Omake.model-error-buffer model))
+         (file (Omake.Error.file-path e))
+         (code-buffer (find-file-noselect file))
+         (ws (Omake.choose-windows id code-buffer))
+         (cw (car ws))
+         (ew (cdr ws))
          (line (Omake.error-line e))
          (char-beg (Omake.error-char-beg e))
          (char-end (Omake.error-char-end e)))
+    ;; This part is finicky.  I'm not sure at the moment why
+    ;; the `switch-to-buffer' call is needed, but it is.
+    (set-window-buffer ew error-buffer)
+    (set-window-buffer cw code-buffer)
+    (select-window cw)
+    (switch-to-buffer code-buffer)
     (remove-overlays (point-min) (point-max))
     (Buffer.goto-line line)
     (forward-char char-beg)
   (assert (Omake.Path.ok dir))
   (concat (Omake.Buffer.prefix kind) dir))
 
-(defun Omake.Buffer.get (kind dir)
-  (assert (Omake.buffer-kind-p kind))
-  (assert (stringp dir))
-  (let ((name (Omake.Buffer.name kind dir)))
-    (unless (buffer-live-p (Buffer.get name)) (error "No such buffer: %s" name))
-    (get-buffer-create name)))
-
 (defun Omake.Buffer.create (kind dir)
   (assert (Omake.buffer-kind-p kind))
   (assert (stringp dir))
 (defconst Omake.File.root "/tmp/omake-server")
 
 ;; CR cfalls: Not all users want this.  Also, you should use custom-set-variables.
+;;    smclaughlin: If this is not set, people get a message every few seconds
+;;                 in the minibuffer.  Maybe I can find a way to set it on a
+;;                 buffer-by-buffer basis.
 (setq auto-revert-verbose nil)
 
 (defun Omake.File.auto-revert (file buffer-name)
   "Show a model in the error buffer"
   (assert (Omake.model-p model))
   (let* ((error-buf (Omake.model-error-buffer model))
-         (error-win (Omake.Window.get Omake.Window.Error)))
+         (error-win (Omake.Window.get 'error)))
     (with-current-buffer error-buf
       (toggle-read-only -1)
       (let ((pt (point))
 
 (defun* Omake.Ping.version-mismatch (&key server-received server-version)
   "Called by the server to alert of a version mismatch"
-  (assert (not (equal server-received server-version)))
+  (assert (nequal server-received server-version))
   (let ((msg
          (if (< server-received server-version)
              (format "Server version (%d) is newer than elisp version (%d).  Run M-x load-library omake" server-version server-received)
 
 (defun Omake.set-dedicated-error-window ()
   (interactive)
-  (Omake.Window.set Omake.Window.Error (selected-window)))
+  (Omake.check-dedicated)
+  (let ((w (selected-window)))
+    (when (equal w (Omake.Window.get 'code))
+      (error "The current window is already dedicated to code.
+Do M-x Omake.clear-dedicated-windows to reset"))
+    (setq Omake.Window.Error w)))
 
 (defun Omake.set-dedicated-code-window ()
   (interactive)
-  (Omake.Window.set Omake.Window.Code (selected-window)))
+  (Omake.check-dedicated)
+  (let ((w (selected-window)))
+    (when (equal w (Omake.Window.get 'error))
+      (error "The current window is already dedicated to errors.
+Do M-x Omake.clear-dedicated-windows to reset"))
+    (setq Omake.Window.Code w)))
+
+(defun Omake.clear-dedicated-windows ()
+  (interactive)
+  (Omake.Window.clear-dedicated))
+
+(defun Omake.set-dedicated-error-frame ()
+  (interactive)
+  (setq Omake.Frame.Error (selected-frame)))
+
+(defun Omake.set-dedicated-code-frame ()
+  (interactive)
+  (setq Omake.Frame.Code (selected-frame)))
 
 (defun Omake.show-error-buffer ()
   (interactive)
-  (if Omake.use-display-buffer
-      (display-buffer (Omake.model-error-buffer (Omake.Model.current)))
-    (let ((error-buffer (Omake.model-error-buffer (Omake.Model.current))))
-      (set-window-buffer (Omake.Window.get Omake.Window.Error) error-buffer))))
-
-(defun Omake.set-standard-windows ()
-  (interactive)
-  (delete-other-windows)
-  (let ((new (split-window-horizontally)))
-    (Omake.set-dedicated-code-window)
-    (with-selected-window new (Omake.set-dedicated-error-window))))
+  (let* ((id (Omake.Id.current))
+         (model (Omake.Model.get id))
+         (eb (Omake.model-error-buffer model))
+         (ws (Omake.choose-windows id nil))
+         (ew (cdr ws)))
+    (set-window-buffer ew eb)))
 
 (defun Omake.compile (&optional read-command)
   "Compile the current directory."
   (Omake.install-hooks)
   (let ((server-was-running (Omake.Server.running-p)))
     (Omake.Server.ensure-running)
-    (when Omake.set-standard-windows (Omake.set-standard-windows))
     (let* ((path (Filename.default-directory))
            (id (Omake.Id.of-path path)))
       (catch 'exit
                                  path
                                  ))))
               (if kill (Omake.Model.kill id) (throw 'exit t)))))
-        ;; Set the code window where the user ran compile
-        (unless (Omake.Window.get Omake.Window.Code)
-          (Omake.Window.set Omake.Window.Code (selected-window)))
-        ;; Set the error window
-        (unless (Omake.Window.get Omake.Window.Error)
-          (Omake.Window.set Omake.Window.Error (Omake.Window.guess-error-window)))
         ;; Create the model
         (let ((user-command
                (when read-command
   (Omake.Model.reset-visited (Omake.Id.current)))
 
 (defun Omake.next-error (&optional user-num)
-  ;; If Omake.use-display-buffer then
-  ;; If I am in the error buffer, then display the code in another buffer
-  ;; If I am not in the error buffer, then display the errors buffer and
-  ;;    display the file in this buffer.
   (interactive "P")
-  (Omake.show-error-buffer)
   (let* ((model (Omake.Model.current))
          (result (Omake.model-result model))
          (current-file (buffer-file-name)))
                      ring)))
         (setf (Omake.model-result model) (Omake.Result.Ring ring))
         (if (Omake.Ring.is-empty ring)
+            (Omake.show-error-buffer)
             (message "There are no errors.")
           (let* ((current (Omake.ring-current ring))
                  (user-num
                       Omake.error-file-dir
                       Omake.user
                       (Omake.date)))
-         (body (format "%s: %s" user msg)))
+         (body (format "%s: %s" Omake.user msg)))
     (Shell.mail "omake-mode error" Omake.maintainer-email-addr msg)))
 ;; (Omake.notify-maintainer-of-error "/mnt/local/sda1/smclaughlin/gord/trunk/")
 
 ;;============================================================================;;
 
 (provide 'omake)
-

window_selection.ml

 
   let choose_windows ~code ~error ~selected_window ~visible_windows =
     (* Requirements that emacs is expected to guarantee. *)
+    assert (code.buffer <> error.buffer);
     assert (code.dedicated_window <> error.dedicated_window);
     (* The algorithm. *)
     let choose_frame_and_maybe_window kind ~other =
       choose_frame_and_maybe_window error ~other:code
     in
     let choice =
-      if code_frame <> error_frame then begin
-        let or_selected window_opt frame =
-          Option.value window_opt ~default:(Frame.selected_window frame)
-        in
-        { code  = or_selected code_window_opt  code_frame ;
-          error = or_selected error_window_opt error_frame;
-        }
-      end
-      else begin
+      if code_frame = error_frame then begin
         let frame = code_frame in
         let selected_window = Frame.selected_window frame in
         let windows = Frame.windows frame in
           | Some code, None -> { code; error = other_than code}
           | None, Some error -> { code = other_than error; error }
           | None, None -> { code = selected_window; error = lru }
+      end else begin
+        let or_selected window_opt frame =
+          Option.value window_opt ~default:(Frame.selected_window frame)
+        in
+        { code  = or_selected code_window_opt  code_frame ;
+          error = or_selected error_window_opt error_frame;
+        }
       end
     in
     (* Properties guaranteed by the algorithm. *)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.