Module: environment-deuce Synopsis: Environment Deuce Author: Scott McKay Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// Support for "Edit Compiler Warnings" //--- For the time being, just keep one "Edit Compiler Warnings" state object define variable *compiler-warnings-state* :: false-or() = #f; define sealed class () sealed constant slot %project :: , required-init-keyword: project:; sealed slot %warnings :: = #[]; sealed slot %index :: = 0; end class ; define method initialize (state :: , #key) => () let project = state.%project; let warnings = project-warnings(project); local method warning-location< (warning1 :: , warning2 :: ) => (less-than? :: ) let loc1 = environment-object-source-location(project, warning1); let loc2 = environment-object-source-location(project, warning2); if (loc1 & loc2) let rec1 = source-location-source-record(loc1); let rec2 = source-location-source-record(loc2); let name1 = source-record-location(rec1); let name2 = source-record-location(rec2); if (name1 = name2) let off1 = source-location-start-offset(loc1); let off2 = source-location-start-offset(loc2); let line1 = source-offset-line(off1); let line2 = source-offset-line(off2); if (line1 = line2) let col1 = source-offset-column(off1); let col2 = source-offset-column(off2); col1 < col2 else line1 < line2 end else as(, name1) < as(, name2) end; else loc1 ~= #f end end method; let warnings = sort(warnings, test: warning-location<); state.%warnings := warnings; state.%index := 0; end method initialize; define command edit-compiler-warnings (frame :: ) "Start editing the compiler warnings for this buffer's project." // Reset to initial state, then fall through to 'edit-next-compiler-warning' *compiler-warnings-state* := #f; edit-next-compiler-warning(frame) end command edit-compiler-warnings; define command edit-next-compiler-warning (frame :: ) "Edit the source for the next compiler warning.\n" "With a negative numeric argument, edit the source for the previous warning." let window :: = frame-window(frame); let buffer :: = frame-buffer(frame); let project = buffer-project(buffer); let direction = if (frame-numeric-arg(frame) < 0) -1 else 1 end; local method initialize-warnings () unless (project) command-error("There is no project for this buffer") end; *compiler-warnings-state* := make(, project: project); deuce/display-message(window, "Editing warnings for project %s", environment-object-primitive-name(project, project)) end method; block (return) let state = *compiler-warnings-state*; case ~state | frame-numeric-arg-state(frame) == #"universal" => initialize-warnings(); state.%project ~== project => let result = yes-no-or-cancel-dialog(window, "Project has changed; get warnings for the new project?"); select (result) #t => initialize-warnings(); #f => #f; otherwise => return(); end; direction > 0 & state.%index >= size(state.%warnings) => let result = yes-no-or-cancel-dialog(window, "No more warnings; get warnings for the project again?"); select (result) #t => initialize-warnings(); #f => return(); otherwise => return(); end; end; let state = *compiler-warnings-state*; let index = state.%index; let warnings = state.%warnings; when (if (direction > 0) index < size(warnings) else index > 0 end) let next = index + direction; let index = if (direction < 0) next else index end; let warning = warnings[index]; let location = environment-object-source-location(project, warning); if (location) let record = source-location-source-record(location); let locator = source-record-location(record); let offset = source-location-start-offset(location); let line = source-record-start-line(record) + source-offset-line(offset) - 1; let column = source-offset-column(offset); state.%index := next; if (find-buffer-from-pathname(frame-editor(frame), locator) == buffer) let line = line-index->line(buffer, line); let bp = if (line) make-bp(line, min(column, deuce/line-length(line))) else interval-start-bp(buffer) end; queue-redisplay(window, $display-point, centering: 0); move-point!(bp) else editor-open-file(locator, start-line: line, start-column: column) end else deuce/display-message(window, "No source for warning: %s", environment-object-display-name(project, warning, #f)) end end; frame-last-command-type(frame) := #"motion" end end command edit-next-compiler-warning;