I want to extract all the coordinates and the text itself of a specific layer into a CSV file. I am using the Mac version of AutoCAD 2018.
DATAEXTRACT seems to be not available on Mac and
-ATTEXT always writes: “0 records in extract file.” With the following template file:
NAME C008000
X N007001
Y N007001
Z N007001
I’ve tried it with lisp as well, but I only got until here:
(defun c:asdf ()
(setq coordinates (assoc 10 (entget (entlast)))))
(alert coordinates)
)
Any ideas?
Thanks in advance!
Sorry for late reply I wrote some function and modified as per your need. load This lisp and type command TEXT2CSV.
then programme asks you for Layer name, Output folder name, and CSV file name. if the input is correct then CSV file create and save on the target location
;
(Defun C:text2CSV (/ extractText FolderBox
makecsvstring lyr layerlist
layerstring
)
;Function-----extractText ---------------------------------------------------------------------
;[filterLIst]--->send selection filter criteria to Function by default nil then select all text
(defun extractText
(filterLIst / outputfile f en i ss name x y z path)
;filterLIst check if filterLIst is nil then select all text from all layer
(if (= nil filterLIst)
(setq filterLIst
'((-4 . "<or") (0 . "TEXT") (0 . "MTEXT") (-4 . "or>"))
)
)
;get file path and file name
;(setq path (FolderBox "Select folder" "D:/" 0))
(setq path (FolderBox "Select Output folder:" "D:/" 0))
(initget 1)
(setq filename (getstring "\nType output CSV filename:"))
(setq outputfile
(strcat path
"/"
filename
".CSV"
)
)
;select entity from dwg and set initial parameter
(setq i -1
ss (ssget "X" filterLIst)
)
;create csv file
(if ss
(progn
(setq f (open outputfile "w"))
(if f
(progn
(write-line (strcat "Name," "X," "Y," "Z,") f)
(while (setq en (ssname ss (setq i (+ 1 i))))
(setq name (makecsvstring (cdr (assoc 1 (entget en)))))
(setq x (rtos (nth 1 (assoc 10 (entget en)))))
(setq y (rtos (nth 2 (assoc 10 (entget en)))))
(setq z (rtos (nth 3 (assoc 10 (entget en)))))
;write to csv
(write-line (strcat name "," X "," Y "," Z) f)
)
(close f)
;done
(Alert "Done!")
)
;if error
(print "\nWrong input unable to create csv file:")
)
)
(print "\nNo text entity found:")
)
(princ)
)
;;---------------------------------------------------------------EnD extractText --------------------------------
;This function to select output folder
(defun FolderBox (message directory flag / folder sh)
;; Arguments:
;; message: the message displayed in th dialog box
;; directory: the directory to browse
;; flag values:
;; 0 = Default
;; 1 = Only file system folders can be selected. If this bit is set, the OK button is disabled if the user selects a folder that doesn't belong to the file system (such as the Control Panel folder).
;; 2 = The user is prohibited from browsing below the domain within a network (during a computer search).
;; 4 = Room for status text is provided under the text box.
;; 8 = Returns file system ancestors only.
;; 16 = Shows an edit box in the dialog box for the user to type the name of an item.
;; 32 = Validate the name typed in the edit box.
;; 512 = None "New folder" button
;; 4096 = Enables the user to browse the network branch of the shell's namespace for computer names.
;; 8192 = Enables the user to browse the network branch of the shell's namespace for printer names.
;; 16384 = Allows browsing for everything.
(vl-load-com)
(setq shell (vlax-create-object "Shell.Application"))
(if (setq
folder (vlax-invoke
shell 'browseforfolder 0 message flag directory)
)
(setq folder
(vlax-get-property (vlax-get-property folder 'self) 'path)
)
(setq folder nil)
)
(vlax-release-object shell)
folder
)
;this function add " to start and end of supply string
(defun makecsvstring (instring)
(if (= nil instring)
(setq instring "")
)
(strcat "\"" instring "\"")
)
;if can send direct layer name
(setq layer (getstring "\nEnter Layer Name:" T))
(if (and (/= layer "") (/= layer nil))
(setq filterLIst
(append
(list (cons 8 layer))
'((-4 . "<or")
(0 . "TEXT")
(0 . "MTEXT")
(-4 . "or>")
)
)
)
(setq filterLIst
'((-4 . "<or")
(0 . "TEXT")
(0 . "MTEXT")
(-4 . "or>")
)
)
;you can Edit for more filter criteria
)
(extractText filterLIst)
)
You can modified code as per your need further Hope this help
Related
So I asked a similar question here about a month ago (Lisp - Extracting info from a list of comma separated values) and managed to put something together that almost meets my needs, but I am hitting a roadblock with a few things. I'll start with the code:
(defun c:poleid ( / fn fp lst l)
;; String to list convertor. This will separate coordinates and values by comma and store them in a variable as a list
(defun LM:str->lst ( str del / len lst pos )
(setq len (1+ (strlen del)))
(while (setq pos (vl-string-search del str))
(setq lst (cons (substr str 1 pos) lst)
str (substr str (+ pos len))
)
)
(reverse (cons str lst))
)
;; Prompt the user to select a .TXT file.
(setq fn (getfiled "Select UTM GPS file" "" "txt" 4))
;; Open the file and create an empty list
(setq fp (open fn "r") lst '())
;; Iterate the file, writing each line to the list (as a string)
(while (setq l (read-line fp))
(setq lst (cons l lst))
)
;; Close the file.
(close fp)
;; Reverse the list
(setq lst (reverse lst))
;; At this point, the data is stored in a variable (lst) and the file is closed.
;; Save current OSNAP MODE and turn off
(setq os (getvar 'osmode))
(setvar "osmode" 0)
;;Set pcount to 0
(setq pcount 0)
;; Iterate the list and draw a point
;; entity at each coordinate
(foreach item lst ;; For each line in lst
(setq items (LM:str->lst item ",")) ;;set variable items as a list of item, separated by commas. Set the las
(setq ptx (nth 2 items) pty (nth 1 items) ptz (nth 3 items) idn (nth 4 items)) ;; Set the pole (pt) x, y and z values from the 2nd, 3rd and 4th values of each line. Set notes to idn (as a string). UTM values are provided to this program as y,x,z
(setq idr (LM:str->lst idn " ") idn (nth 0 idr) idr (nth 1 idr)) ;;Set idr (Pole ID) as a list of idn, then set idn as the first half of the note (HP#) and idr as the second half
(cond ((wcmatch idn "HP") ;; Only process lines that have HP in the 5th value
(
(printc idn)
(setq ptxyz (strcat ptx "," pty "," ptz)) ;;Make the pole x, y, and z value into a single string, separated by commas
(setq idx (atof ptx) idx (- idx 5.0) idx (rtos idx)) ;;set the idx as real number version of ptx, subtract 5 from it, then convert back to a string
(setq idxyz (strcat idx "," pty "," ptz)) ;;Make the ID x, y, and z value into a single string, separated by commas
;;Insert pole and ID block at xyz coords, with idn as the HP number and idr as the pole ID
(command "insert" "G:\\Shared drives\\Project Tools\\Customized Tools\\CAD\\prog\\CWood_Pole_D.dwg" ptxyz "508" "508" "0") ;; Pole symbol set to an x/y scale of 20
(command "insert" "G:\\Shared drives\\Project Tools\\Customized Tools\\CAD\\prog\\POLENA.dwg" idxyz "25.4" "25.4" "0" idn idr) ;; Pole ID block set to an x/y scale of 1, with the top half showing the HP# and the bottom half showing the pole ID
(setq pcount (+ pcount 1)) ;;Add 1 to counter
))
)
)
;; Restore OSNAP MODE and close with count of poles inserted
(setvar 'osmode os)
(setq pcount (write-to-string pcount))
(princ pcount)
(princ " pole(s) have been successively added")
(princ)
)
This is fed a .txt file that contains GPS points. The test example I have been feeding the script is:
1000,1,2,3,HP
1001,10.000,2.000,3.000,HP21 blah
1002,15.000,2.000,3.000,HP22 2gt3
1003,20.000,2.000,3.000,CU
#,Easting,Northing,Elevation,Notes
What I want the code to do is insert a block (CWood_Pole_D.dwg) in at the Easting/Northing/Elevation, and then insert a second block (POLENA.dwg) 5 units to the left of that point. The second block contains two attributes, which I would like to pull from the notes (with the two attributes separated by a space). All of this should only happen when the notes begin with "HP" (which may be followed bynumbers and a letter, ex. HP22A). The last little bit just counts up each time a pair of blocks is successfully added, but even that is spitting out a .
The problem I am having is dealing with the notes part, and conversely the loop activating when the notes are anything but JUST "HP". I'm also sure there is a bunch of redundancy or useless code, but boy oh boy is it difficult to find good information that breaks down all the individual actions (like, what is happening with the Lee Mac string to list convertor?)
I think the match does not work:
(wcmatch idn "HP")
You can try this instead, you may need a wildcard to match e.g. "HP22":
(wcmatch idn "HP*")
The rest is fine, I'd encourage to split your setq into distinct lines for readability.
I'm trying to make drawing wiring diagrams extremely easy in AutoCAD with next to no button presses other than my pre-programmed ones.
One involves a LISP that is not playing nicely with setting system variables and then resetting them to what they were previously. The program seems to perform the intended function, but not with the intended results.
Once my PLINE command starts, the variables get reset. I need the PLINE to start, finish, and then the variables get reset.
I've tried setting OrthoMode and SnapMode within a command in the LISP, as well as through the (setvar (getvar ...)) commands.
(defun varget ()
(setq lis '("orthomode" "snapmode"))
(setq var (mapcar 'getvar lis))
(setq var1 '(1 1))
(setq no 0)
(repeat (length lis)
(setvar (nth no lis) (nth no var1))
(setq no (1+ no))
)
(princ)
)
(defun varset ()
(setq no 0)
(repeat (length lis)
(setvar (nth no lis) (nth no var))
(setq no (1+ no))
)
(princ)
)
(princ)
(defun C:wire ()
(progn
(varget)
(setq prevlayer (getvar "clayer"))
(setq P (getstring "Audio(A)/Video(V)/Comm(CO)/Coax(R)/Control(C)/(N)etwork/(P)ower:"))
(IF (= P "V")(command "-LAYER" "M" "VIDEO" "C" "150" "" "" "PLINE" PAUSE))
(IF (= P "A")(command "-LAYER" "M" "AUDIO" "C" "94" "" "" "PLINE" PAUSE))
(IF (= P "CO")(command "-LAYER" "M" "COMM" "C" "206" "" "" "PLINE" PAUSE))
(IF (= P "R")(command "-LAYER" "M" "COAX" "C" "44" "" "" "PLINE" PAUSE))
(IF (= P "C")(command "-LAYER" "M" "CONTROL" "C" "10" "" "" "PLINE" PAUSE))
(IF (= P "N")(command "-LAYER" "M" "NETWORK" "C" "210" "" "" "PLINE" PAUSE))
(IF (= P "P")(command "-LAYER" "M" "POWER" "C" "7" "" "" "PLINE" PAUSE))
(setvar "clayer" prevlayer)
(varset)
(princ)
);Progn
);defun
No error messages.
I expect the variables to be reset after performing the PLINE command.
The issue with your code is that you are only pausing for a single user input before attempting to reset the system variables and complete evaluation of the program.
Instead, you will need to use a loop to continuously pause for user input before continuing with program evaluation.
For example:
;; Define function, declare local symbols
(defun c:wire ( / col lay opt val var )
;; System variables to be modified within the program
(setq var '(clayer orthomode snapmode cmdecho)
;; Retrieve current sys var values
val (mapcar 'getvar var)
) ;; end setq
;; Predefine the getkword options
(initget "Audio Video COmm R Control Network Power")
;; Prompt the user for input, default to "Audio" on null input
(setq opt (cond ((getkword "\n[Audio/Video/COmm/Coax(R)/Control/Network/Power] <Audio>: ")) ("Audio")))
;; Define the layer & colour based on the option returned
(cond
( (= opt "Audio") (setq lay "AUDIO" col 94))
( (= opt "Video") (setq lay "VIDEO" col 150))
( (= opt "COmm") (setq lay "COMM" col 206))
( (= opt "R") (setq lay "COAX" col 44))
( (= opt "Control") (setq lay "CONTROL" col 10))
( (= opt "Network") (setq lay "NETWORK" col 210))
( (= opt "Power") (setq lay "POWER" col 7))
) ;; end cond
;; Suppress command-line output for the -LAYER command
(setvar 'cmdecho 0)
;; Create & set the layer & layer colour
(command "_.-layer" "_M" lay "_C" col "" "")
;; Set everything except the first sys var
(mapcar 'setvar (cdr var) '(1 1 1))
;; Initiate the PLINE command
(command "_.pline")
;; Continuously pause for user input
(while (= 1 (logand 1 (getvar 'cmdactive))) (command "\\"))
;; Reset system variables
(mapcar 'setvar var val)
;; Suppress the value returned by the last evaluated expression
(princ)
) ;; end defun
A few points to note:
Always declare your local variables to avoid clashing with identically named variables in the document namespace. See my tutorial here for more information on how & why you do this.
Use getkword in place of getstring to control & validate the user's input.
Use "\\" in place of the pause symbol, as the pause symbol is an unprotected global variable and can easily be inadvertently redefined outside of your program, causing your program to break. Since the pause symbol evaluates to "\\" you may as well use the literal backslash.
As an extension, you may also want to consider implementing a local error handler to handle when the user inevitably presses Esc during evaluation of the program (the system variables would otherwise not be reset under such circumstances). I describe how to do this in my tutorial here.
Here is a basic example demonstrating the inclusion of a local error handler:
;; Define function, declare local symbols
(defun c:wire ( / *error* col lay opt val var )
;; Define local error handler
(defun *error* ( msg )
;; Reset system variables
(mapcar 'setvar var val)
;; Suppress the output of standard cancellation messages
(if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
;; Print critical errors
(princ (strcat "\nError: " msg))
) ;; end if
(princ) ;; Suppress the value returned by the last evaluated expression
) ;; end defun
;; System variables to be modified within the program
(setq var '(clayer orthomode snapmode cmdecho)
;; Retrieve current sys var values
val (mapcar 'getvar var)
) ;; end setq
;; Predefine the getkword options
(initget "Audio Video COmm R Control Network Power")
;; Prompt the user for input, default to "Audio" on null input
(setq opt (cond ((getkword "\n[Audio/Video/COmm/Coax(R)/Control/Network/Power] <Audio>: ")) ("Audio")))
;; Define the layer & colour based on the option returned
(cond
( (= opt "Audio") (setq lay "AUDIO" col 94))
( (= opt "Video") (setq lay "VIDEO" col 150))
( (= opt "COmm") (setq lay "COMM" col 206))
( (= opt "R") (setq lay "COAX" col 44))
( (= opt "Control") (setq lay "CONTROL" col 10))
( (= opt "Network") (setq lay "NETWORK" col 210))
( (= opt "Power") (setq lay "POWER" col 7))
) ;; end cond
;; Suppress command-line output for the -LAYER command
(setvar 'cmdecho 0)
;; Create & set the layer & layer colour
(command "_.-layer" "_M" lay "_C" col "" "")
;; Set everything except the first sys var
(mapcar 'setvar (cdr var) '(1 1 1))
;; Initiate the PLINE command
(command "_.pline")
;; Continuously pause for user input
(while (= 1 (logand 1 (getvar 'cmdactive))) (command "\\"))
;; Reset system variables
(mapcar 'setvar var val)
;; Suppress the value returned by the last evaluated expression
(princ)
) ;; end defun
I'm using a function that uses a mapcar to apply a (simple) function to all members of a list, like this :
(mapcar 'my-concat-function '(
"/path/one.php"
"/path/two.php"))
But I want to use directory-files to generate the file list and filter it, something like this :
(mapcar 'my-concat-function '(
(directory-files "/path/" nil "\\.php$")))
But I always get a
find-file-noselect: Wrong type argument: stringp, (directory-files "/path/" nil "\\.php$")
When I evaluate
(directory-files "/path/" nil "\\.php$")
It returns
("one.php" "two.php" "three.php" ...)
(I did not add the "..." ; Emacs did. No matter the size of the list, it seems to always end with "...")
Question :
How can I format the output of directory-files so that it produces exactly what mapcar wants, a single list of atoms, I don't really know how to call this form :
"one.php" "two.php" "three.php"
Without the parenthesis, and without those weird "..."?
EDIT
When I try the forms suggested (thank you guys) the quoted function as 1st arg of mapcar does not work (the regexp don't find anything, all files end up open in empty (?) buffers) anymore :(
Here is the full code, thank you very much for helping, it's weird, this function took very little time to write, and now i'm blocked since hours on this simple list issue, arg.
(defun px-bpm-parse (fname)
"Extract elements. Basic Project Management."
(setq in-buf (set-buffer (find-file fname)))
(setq u1 '())
(setq u2 '())
(setq u3 '())
(setq project-dir "/var/www/html/microlabel.git/")
(beginning-of-buffer)
(while
(re-search-forward "^.*<link.*href=\"\\([^\"]+\\)\".*rel=\"stylesheet\"" nil t)
(when (match-string 0)
(setq url (match-string 1) )
(setq u3 (cons (concat "[[file:" project-dir url "][" url "]]\n") u3))))
(beginning-of-buffer)
(while
(re-search-forward "^.*<a.*href=\"\\([^\"]+\\)\"[^>]+>\\([^<]+\\)</a>" nil t)
(when (match-string 0)
(setq url (match-string 1) )
(setq title (match-string 2) )
(setq u1 (cons (concat "[[file:" project-dir url "][" title "]]\n") u1))))
(beginning-of-buffer)
(while
(re-search-forward "^.*<script.*src=\"\\([^\"]+\\)\"" nil t)
(when (match-string 0)
(setq url (match-string 1) )
(setq u2 (cons (concat "[[file:" project-dir url "][" url "]]\n") u2))))
(beginning-of-buffer)
(progn
(with-current-buffer "BPM.org"
(insert "** File: ")
;; (org-insert-link &optional COMPLETE-FILE LINK-LOCATION DEFAULT-DESCRIPTION)
(insert fname)
(insert "\n*** HREF Links (by name)\n")
(mapcar 'insert u1)
(insert "\n*** SCRIPT Links\n")
(mapcar 'insert u2)
(insert "\n*** CSS Links\n")
(mapcar 'insert u3)
(insert "\n\n"))
(switch-to-buffer "BPM.org")
(org-mode)))
(defun px-bpm ()
;; (defun px-bpm (prj-root)
"List all links"
(interactive)
;; (interactive "sEnter project root directory ")
(progn
(with-current-buffer (get-buffer-create "BPM.org")
(insert "* File dependencies\n\n"))
;; (mapcar 'px-bpm-parse '(
;; "/var/www/html/microlabel.git/add.php"
;; ))
(mapcar 'px-bpm-parse (directory-files "/var/www/html/microlabel.git/" nil "\\.php$"))
))
When you evaluate a form and see a result of the form (x y z ...), it's just printed in that way because the output is long. The result is actually the list that you'd expect. For instance,
(list 1 2 3 4 5 6 7 8 9 10 11 12 13)
;=> (1 2 3 4 5 6 7 8 9 10 11 12 ...)
Yet, the last element of the list is what it should be:
(last (list 1 2 3 4 5 6 7 8 9 10 11 12 13))
;=> (13)
Since (directory-files "/path/" nil "\\.php$") returns a list and the second argument to mapcar should be a list, you can make it the second argument:
(mapcar 'my-concat-function (directory-files "/path/" nil "\\.php$"))
I have this script as an .scm in Gimp:
;MIT license.
(define (script-fu-export-layers img drw path outnameformat)
; credit to Vijay Mathew on Stack Overflow for the expand keywords function
(let ((expand-keywords (lambda(format tokens)
(let loop ((slist (string->list string))
(in-replace-mode #f)
(result ""))
(if (not (null? slist))
(let ((c (car slist)))
(cond (in-replace-mode
(let ((token (car (cdr (assoc c tokens)))))
(loop (cdr slist) #f (string-append result token))))
((char=? c #\~)
(loop (cdr slist) #t result))
(else
(loop (cdr slist) #f (
string-append result (make-string 1 c))))))
result)))))
(for-each (lambda (layer)
(let* (
(name (expand-keywords outnameformat '(
(#\i (car(gimp-image-get-name img)))
(#\l (car(gimp-drawable-get-name layer))))))
(outpath (string-append path "/" name)))
(gimp-file-save RUN-NONINTERACTIVE img layer outpath name)
)) (vector->list(cadr (gimp-image-get-layers img)))))
)
(script-fu-register
"script-fu-export-layers"
"L_ayers"
"Export all layers as individual files."
"Stuart P. Bentley <stuart#testtrack4.com>"
"Copyright 2011 Stuart P. Bentley"
"June 28, 2011"
"*"
SF-IMAGE "The Image" 0
SF-DRAWABLE "The Layer" 0
SF-DIRNAME "Output directory" ""
SF-STRING "Filename Format (~i = image name, ~l = layer name)"
"~i-~l.png"
)
(script-fu-menu-register "script-fu-export-layers" "<Image>/File/E_xport")
With the comment at the top of the file, the script doesn't load at all. When the comment is removed, GIMP throws an error when refreshing scripts that "Error while loading C:\Users\Stuart.gimp-2.6\scripts\export-layers.scm: Error: unmatched parentheses: 1". I don't know what that's about, since it parses fine when I run it on Codepad (it breaks at the script-fu-register point).
This behavior is consistent with what would happen if the line endings were missing (the comments commenting out all subsequent text). Check to make sure your editor isn't doing something ridiculous like saving your file with CR line endings on Windows.
A lot of Emacs functions automatically split the screen. However, they all do so such that the windows are one on top of the other. Is there any way to make them split such that they are side-by-side by default instead?
(setq split-height-threshold nil)
(setq split-width-threshold 0)
GNU Emacs Lisp Reference Manual: Choosing Window Options
Two solutions here, use any one you like:
A: Vertically(left/right) by default:
(setq split-height-threshold nil)
(setq split-width-threshold 0)
B: Automatically split window vertically(left/right) if current window is wide enough
(defun display-new-buffer (buffer force-other-window)
"If BUFFER is visible, select it.
If it's not visible and there's only one window, split the
current window and select BUFFER in the new window. If the
current window (before the split) is more than 100 columns wide,
split horizontally(left/right), else split vertically(up/down).
If the current buffer contains more than one window, select
BUFFER in the least recently used window.
This function returns the window which holds BUFFER.
FORCE-OTHER-WINDOW is ignored."
(or (get-buffer-window buffer)
(if (one-window-p)
(let ((new-win
(if (> (window-width) 100)
(split-window-horizontally)
(split-window-vertically))))
(set-window-buffer new-win buffer)
new-win)
(let ((new-win (get-lru-window)))
(set-window-buffer new-win buffer)
new-win))))
;; use display-buffer-alist instead of display-buffer-function if the following line won't work
(setq display-buffer-function 'display-new-buffer)
Put any one in you .emacs/init.el file.
You can change the "100" to the value you like, depending on you screen.
If you got two windows in one frame, and you want to change the layout from vertical to horizontal or vice verse, here is a solution:
(defun toggle-window-split ()
(interactive)
(if (= (count-windows) 2)
(let* ((this-win-buffer (window-buffer))
(next-win-buffer (window-buffer (next-window)))
(this-win-edges (window-edges (selected-window)))
(next-win-edges (window-edges (next-window)))
(this-win-2nd
(not (and (<= (car this-win-edges)
(car next-win-edges))
(<= (cadr this-win-edges)
(cadr next-win-edges)))))
(splitter
(if (= (car this-win-edges)
(car (window-edges (next-window))))
'split-window-horizontally
'split-window-vertically)))
(delete-other-windows)
(let ((first-win (selected-window)))
(funcall splitter)
(if this-win-2nd (other-window 1))
(set-window-buffer (selected-window) this-win-buffer)
(set-window-buffer (next-window) next-win-buffer)
(select-window first-win)
(if this-win-2nd (other-window 1))))))
;; C-x 4 t 'toggle-window-split
(define-key ctl-x-4-map "t" 'toggle-window-split)
Put it in your .emacs/init.el file, Use C-x 4 t to toggle the layout of your windows.
(setq split-height-threshold 0) (setq split-width-threshold 0)
is what i had to use to get the desired behaviour (no horizontal splitting)
Sometimes we need change between Horizontal and Vertical according current display and our requirement (more lines or more columns).
I recommand the great ToggleWindowSplit, And I bind key to "C-c y"
http://www.emacswiki.org/emacs/ToggleWindowSplit
the simple answer of setting 2 variables to nil and 0 didn't work for me, so I wrote 2 simple functions: one just splits the window into NX vertical buffers and opens files named (for example) file.1 file.2 ... file.NX in each and another one does the same think, except does it in 2D (NY rows by NX columns for opening files f.1 f.2 ... f.[NX*NY]). To install, add this code to .emacs:
(defun grid-files-h (nx wx pfx)
"Using dotimes, split the window into NX side-by-side buffers of width WX and load files starting with prefix PFX and ending in numbers 1 through NX"
(let (ox fn k) ; ox is not used, but fn is used to store the filename, and k to store the index string
(dotimes (x (- nx 1) ox) ; go through buffers, x goes from 0 to nx-2 and ox is not used here
; (print x)
(setq k (number-to-string (+ x 1) ) ) ; k is a string that goes from "1" to "nx-1"
; (print k)
(setq fn (concat pfx k) ) ; fn is filename - concatenate prefix with k
; (print fn)
(find-file fn) ; open the filename in current buffer
(split-window-horizontally wx) ; split window (current buffer gets wx-columns)
(other-window 1) ; switch to the next (right) buffer
)
(setq k (number-to-string nx )) ; last (rightmost) buffer gets the "nx" file
(setq fn (concat pfx k) ) ; fn = "pfx"+"nx"
(find-file fn ) ; open fn
(other-window 1) ; go back to the first buffer
)
)
(defun grid-files-sq (ny wy nx wx pfx)
"Using dotimes, split the window into NX columns of width WX and NY rows of height WY and load files starting with prefix PFX and ending in numbers 1 through NX*NY"
(let (oy ox fn k)
(dotimes (y ny oy) ; go through rows, y goes from 0 to ny-1 and oy is not used here
(split-window-vertically wy) ; create this row
(dotimes (x (- nx 1) ox) ; go through columns, x goes from 0 to nx-2 and ox is not used here
(setq k (number-to-string (+ 1 (+ x (* y nx) ) ) ) ) ; k must convert 2 indecies (x,y) into one linear one (like sub2ind in matlab)
(setq fn (concat pfx k) ) ; filename
(find-file fn ) ; open
(split-window-horizontally wx) ; create this column in this row (this "cell")
(other-window 1) ; go to the next buffer on the right
)
(setq k (number-to-string (+ nx (* y nx) ) ) ) ; rightmost buffer in this row needs a file too
(setq fn (concat pfx k) ) ; filename
(find-file fn ) ; open
(other-window 1) ; go to next row (one buffer down)
)
)
)
and then to use the vertical one, I go to *scratch* (C-x b *scratch* RET,C-x 1), type in (grid-files-h 3 20 "file.") then C-x C-e, or if you want to test out the square qrid one, C-x 1, type in (grid-files-sq 2 15 3 20 "f.") and then C-x C-e and you should see something like
This probably can be done better/more efficiently, but it's a start and it does what I need it to do (display a bunch of sequentially named small files). Feel free to improve or reuse.
I use multiple frames (OSX windows) in emacs regularly for different projects. Here's how I setup a few frames initially split to a left and right window.
(defun make-maximized-split-frame (name)
(let (( f (make-frame (list (cons 'name name))) ))
(maximize-frame f)
(split-window (frame-root-window f) nil t)
))
(make-maximized-split-frame "DocRaptor")
(make-maximized-split-frame "Gauges")
(make-maximized-split-frame "Instrumental")
The direct answer is to press C-c 3.
It's not clear from the question if you want a permanent setting change, but I found this question looking for this answer and didn't find it. (The answer has actually been sitting in a comment for the last 11 years)