Install Emacs on Windows 10
Emacs 설치
https://www.gnu.org/software/emacs/ 에서 이맥스를 다운받아 설치합니다.
환경 변수 설정
HOME 환경변수를 추가합니다.
Emacs 실행
우선 Emacs 를 실행시켜 봅니다.
(설치된 폴더 안에 bin 디렉토리가 있는데 그 안으로 들어가면 emacs.exe 가 있습니다.)
가장 중요한 Ctrl-C/Ctrl-V 가 오작동하는것을 교정하기 위해 아래 설정을 합니다.
메뉴 > Options > Use CUA Keys 체크.
폰트가 맘에 않들면 아래와 같이 합니다.
메뉴 > Options > Set Default Font 를 선택하면 폰트를 고를 수 있습니다.
툴바가 않이쁘면 아래와 같이 합니다.
메뉴 > Options > Show/Hide > Tool-bar
옵션정보를 저장하지 않으면 이맥스를 재실행 했을 때 다시 폰트가 디폴트로 바뀝니다.
그래서 메뉴 > Options > Save Option 를 선택해서 옵션정보를 저장해 줍니다.
이맥스를 종료합니다.
Emacs 설정 변경하기
이맥스를 실행하고, C-X C-F 를 입력 후 ~/.emacs 파일을 열어줍니다.
아래 내용을 입력해 줍니다.
아래 내용을 적용하기 위해 필요한 명령은 다음과 같습니다.
파일열기 : C-X C-F (Find)
파일저장 : C-X C-S (Save)
이맥스종료 : C-X C-C (Close)
;; -*- coding: utf-8 -*-
;; =============================================================================
;; 시작하기 전에
;; =============================================================================
;; - 메뉴 > Options > Use CUA Keys 체크
;; - 메뉴 > Options > Show/Hide > Tool-bar 체크해제
;; - 메뉴 > Options > Set Default Font
;; - 메뉴 > Options > Save Options
;; - C-x C-c 로 이맥스를 종료 후 재실행한다.
;; =============================================================================
;; 패키지 시스템(MELPA)
;; =============================================================================
(require 'package)
;; 패키지 사이트(org, melpa) 추가
;; (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)
;; 패키지 시스템 초기화
(package-initialize)
(defalias 'lp 'list-packages)
;; =============================================================================
;; use-package
;;
;; 샘플코드
;; (use-package helm
;; :ensure t ;; 패키지가 설치 안되어 있으면 설치
;; :init ;; 패키지 로딩 전 실행
;; (add-hook 'after-init-hook 'helm-mode)
;; :config ;; 패키지 로딩 후 실행
;; (helm-autoresize-mode 1))
;; =============================================================================
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(require 'use-package)
;; =============================================================================
;; 기본 설정
;; =============================================================================
(add-to-list 'load-path (expand-file-name "~/my-package"))
;; 튜토리얼 메시지 없애기
(setq inhibit-startup-message t)
;; 상태표시줄에 가로 세로 위치 표시
(column-number-mode t)
(line-number-mode t)
;; yes/no 입력 대신 y/n 입력하도록 변경
(fset 'yes-or-no-p 'y-or-n-p)
;; remove all trailing space when you save
(add-hook 'write-file-hooks
'delete-trailing-whitespace)
;; 미니버퍼 히스토리를 저장한다.
(savehist-mode 1)
;; 대응하는 괄호 자동입력
(when (>= emacs-major-version 24)
(electric-pair-mode 1))
;; 윈도우 제목 설정
(setq frame-title-format "Emacs - %b")
(setq icon-title-format "Emacs - %b")
;; 커서가 깜빡임 중단 안하기
(setq blink-cursor-blinks 0)
;; 자동 줄바꿈 안하기
(setq-default truncate-lines 1)
;; 백업파일 위치 지정
(setq backup-directory-alist '(("" . "~/.emacs.d/emacs-backup")))
;; 도움말 표시기능 사용한함
(setq global-eldoc-mode nil)
;; =============================================================================
;; 기본키 변경
;;
;; C-a (라인 맨 처음으로 이동 => 전체 선택)
;; C-e (라인 끝으로 이동 => 현재 라인 삭제)
;; C-f (커서 오른쪽으로 이동 => 검색)
;; C-s (검색 => 저장)
;; <F1> (도움말 => 현재창 하나만 남기기)
;; C-l (버퍼 내 커서이동 => 라인 이동)
;; =============================================================================
;; select all
(define-key global-map (kbd "C-a") 'mark-whole-buffer)
;; DELETE LINE
(defun delete-whole-line ()
"delete whole line"
(interactive)
(delete-region (line-beginning-position) (line-end-position))
(if (>= (point-max) (point))
(delete-char 1)))
(define-key global-map (kbd "C-e") 'delete-whole-line)
;; 증가검색 단축키 변경(isearch)
(define-key global-map (kbd "C-f") 'isearch-forward)
;; 증가검색 단축키 변경(isearch)
(add-hook 'isearch-mode-hook
(lambda ()
(define-key isearch-mode-map (kbd "C-f") 'isearch-repeat-forward)
(define-key isearch-mode-map (kbd "C-v") 'isearch-yank-kill)))
;; 저장하기 단축키 변경(save-buffer)
(global-set-key (kbd "C-s") 'save-buffer)
;; 현재 창만 남기고 다른 창 모두 닫기
(define-key global-map (kbd "<f1>") 'delete-other-windows)
;; goto-line
(define-key global-map (kbd "C-l") 'goto-line)
;; =============================================================================
;; 나만의 키 설정
;; =============================================================================
;; M-x 대용
(global-set-key (kbd "<f8>") 'execute-extended-command)
;; 현재 창 닫기
(define-key global-map (kbd "C-x c") 'kill-this-buffer)
;; 현재파일의 인코딩 변경
(global-set-key (kbd "C-c u") (lambda() (interactive) (set-buffer-file-coding-system 'utf-8) (message "Encoding changed to UTF-8")))
(global-set-key (kbd "C-c k") (lambda() (interactive) (set-buffer-file-coding-system 'cp949) (message "Encoding changed to CP949")))
;; ============================================================================
;; SMART HOME KEY
;; ============================================================================
(defun smart-beginning-of-line ()
"Move point to first non-whitespace character or beginning-of-line."
(interactive "^") ; Use (interactive "^") in Emacs 23 to make shift-select work
(let ((oldpos (point)))
(back-to-indentation)
(and (= oldpos (point))
(beginning-of-line))))
;; CUA 모드에서 Shift Home 이 정상적으로 작동하게 설정
;;(put 'smart-beginning-of-line 'CUA 'move)
(global-set-key (kbd "<home>") 'smart-beginning-of-line)
;; ============================================================================
;; 최근 열었던 파일 가져오기
;; ============================================================================
(recentf-mode 1)
;; 최근열었던 파일 1200까지 저장하기
(setq recentf-max-saved-items 1200)
;; 제외할 파일
(add-to-list 'recentf-exclude "Temporary Internet Files")
(add-to-list 'recentf-exclude "/.emacs.d/recentf")
;; 자동 저장기능 활성화
;; (setq recentf-auto-save-timer
;; (run-with-idle-timer 60 t 'recentf-save-list))
(global-set-key [f12] 'recentf-open-files)
;; ============================================================================
;; 상태표시줄에 디렉토리를 포함한 파일명 표시
;; ============================================================================
(setq-default mode-line-buffer-identification
(list 'buffer-file-name
(propertized-buffer-identification "%12f")
(propertized-buffer-identification "%12b")))
(add-hook 'dired-mode-hook
(lambda ()
;; TODO: handle (DIRECTORY FILE ...) list value for dired-directory
(setq mode-line-buffer-identification
;; emulate "%17b" (see dired-mode):
'(:eval
(propertized-buffer-identification
(if (< (length default-directory) 17)
(concat default-directory
(make-string (- 17 (length default-directory))
?\s))
default-directory))))))
;; ============================================================================
;; 단축명령
;; ============================================================================
(defalias 'qrr 'query-replace-regexp)
(defalias 'qr 'query-replace)
(defalias 'sh 'shell)
(defalias 'eb 'eval-buffer)
(defalias 'er 'eval-region)
(defalias 'ed 'eval-defun)
;; ============================================================================
;; Only on Windows-NT Emacs
;; ============================================================================
;; 이맥스 서버모드 활성화
(if (eq system-type 'windows-nt)
(server-start)
(message "* Running with server"))
;; ============================================================================
;; 커서위치 저장하기
;; ============================================================================
;; 파일 편집 위치 기억
(if (< emacs-major-version 25)
(progn
(require 'saveplace)
(setq-default save-place t))
(save-place-mode 1))
;; ============================================================================
;; 선택 영역 검색
;; ============================================================================
(defvar search-selection-last-searched-string nil)
(defun search-selection-or-last-searched (direction)
"search for selected or last searched text"
(let ((search-str search-selection-last-searched-string))
(when (region-active-p)
(setq search-str (buffer-substring (region-beginning) (region-end)))
(setq search-selection-last-searched-string search-str))
(if search-str
(cond ((eq direction 'forward)
(when (search-forward search-str nil t 1)
(deactivate-mark)
(setq found t)
(set-mark (- (point) (length search-str)))))
((eq direction 'backward)
(when (search-backward search-str nil t 1)
(deactivate-mark)
(setq found t)
(set-mark (+ (point) (length search-str)))))
(t
(beep)
(message "Unknown error.")))
(beep)
(message "No keyword for search."))))
(define-key global-map (kbd "<f3>") (lambda() (interactive) (search-selection-or-last-searched 'forward)))
(define-key global-map (kbd "C-<f3>") (lambda() (interactive) (search-selection-or-last-searched 'backward)))
;; ============================================================================
;; 버퍼 선택 툴
;; ============================================================================
(require 'bs)
(global-set-key [C-tab] 'bs-show)
;; (setq bs-default-configuration "all")
(setq bs-default-configuration "files-and-scratch")
(defun my-bs--get-modification-time-string (_start-buffer _all-buffers)
"Return last modified time of file"
(let ((file (buffer-file-name)))
(if (and file (listp (visited-file-modtime)))
(if (eq (car (visited-file-modtime)) -1)
(string)
(format-time-string "%Y-%m-%d %H:%M:%S" (visited-file-modtime)))
(string))))
(setq bs-attributes-list
'(("" 1 1 left bs--get-marked-string)
("M" 1 1 left bs--get-modified-string)
("R" 2 2 left bs--get-readonly-string)
("Buffer" 50 50 left bs--get-name)
("" 2 2 left " ")
("Size" 8 8 right bs--get-size-string)
("" 2 2 left " ")
("Last Modified" 19 19 left my-bs--get-modification-time-string)
("" 2 2 left " ")
("Mode" 20 20 left bs--get-mode-name)
("" 2 2 left " ")
("File" 20 20 left bs--get-file-name)))
;; =============================================================================
;; paste-and-indent
;; =============================================================================
(defun paste-and-indent ()
(interactive)
(if (and cua-delete-selection (region-active-p))
(cua-delete-region))
(yank)
(indent-region (save-excursion (exchange-point-and-mark) (point)) (point)))
(global-set-key "\C-y" 'paste-and-indent)
;; =============================================================================
;; MS Windows 입력기 사용않함
;; 필요 : AutoHotkey, https://www.skyer9.pe.kr/wordpress/?p=5001
;; =============================================================================
(set-language-environment "Korean")
(setq default-input-method "korean-hangul")
(global-set-key (kbd "<S-SPC>") 'toggle-input-method)
;; (global-set-key (kbd "<Hangul>") 'toggle-input-method)
;; (global-set-key [(kana)] 'toggle-input-method)
(global-set-key [(kanji)] 'hangul-to-hanja-conversion)
;; =============================================================================
;; 북마크
;; =============================================================================
;; 북마크 설정시 자동저정
(setq bookmark-save-flag 1)
(global-set-key [f9] 'bookmark-bmenu-list)
(global-set-key [C-f9] 'bookmark-set)
;; =============================================================================
;; auto-complete
;; (필요 : melpa, auto-complete)
;; =============================================================================
(use-package auto-complete
:ensure t)
(require 'auto-complete-config)
;; 자동완성 활성화
(global-auto-complete-mode t)
;; 2글자 입력시 자동완성 시작
(setq ac-auto-start 2)
;; 0.1 초 후 목록 표시함
(setq ac-auto-show-menu 0.1)
(ac-config-default)
;; TAB 키 누르면 자동완성 시작
(ac-set-trigger-key "TAB")
;; 활성화할 모드 추가(M-x major-mode RET)
(add-to-list 'ac-modes 'sql-mode)
(add-to-list 'ac-modes 'text-mode)
;; =============================================================================
;; yasnippet
;; (필요 : melpa, yasnippet)
;; =============================================================================
(use-package yasnippet
:ensure t)
;; yasnippet 활성화
(yas-global-mode 1)
;; Remove Yasnippet's default tab key binding
(define-key yas-minor-mode-map (kbd "<tab>") nil)
(define-key yas-minor-mode-map (kbd "C-c y") 'yas-expand)
;; prog mode
(add-hook
'prog-mode-hook
(lambda ()
(setq ac-sources
(append '(ac-source-yasnippet) ac-sources))))
;; =============================================================================
;; cursor-chg
;; (필요 : https://www.emacswiki.org/emacs/cursor-chg.el)
;; =============================================================================
(require 'cursor-chg)
(change-cursor-mode 1)
;; 기본 커서 색상
;; (setq curchg-default-cursor-color "Black")
;; 한글 입력시 커서 색상
;;(setq curchg-input-method-cursor-color "Red")
;; 기본 커서 모양
(setq curchg-default-cursor-type 'bar)
;; 덮어쓰기 또는 read-only 버퍼일 때 커서 모양
(setq curchg-overwrite/read-only-cursor-type 'box)
;; =============================================================================
;; Visual bookmark
;; (필요 : MELPA, bm)
;; =============================================================================
(use-package bm
:ensure t)
;; M$ Visual Studio key setup.
(global-set-key (kbd "<C-f2>") 'bm-toggle)
(global-set-key (kbd "<f2>") 'bm-next)
(global-set-key (kbd "<S-f2>") 'bm-previous)
;; =============================================================================
;; MinGW 설정
;; (필요 : http://www.mingw.org/)
;; 추가로 ~/.bashrc 에 패스를 다음과 같이 추가해 주어야 한다.
;; export PATH=/bin:/usr/bin:$PATH
;; =============================================================================
(setq shell-file-name "bash.exe")
(setq explicit-shell-file-name "C:/MinGW/msys/1.0/bin/bash.exe")
(setq exec-path (cons "C:/MinGW/msys/1.0/bin/" exec-path))
;; =============================================================================
;; browse-kill-ring
;; (필요 : MELPA, browse-kill-ring)
;; =============================================================================
(use-package browse-kill-ring
:ensure t)
;; 여러 라인의 복사본을 한줄로 표시(separator 표시 않함)
(setq browse-kill-ring-display-style 'one-line)
;; 복사본 추가시 중복되는 복사본 삭제(browse-kill-ring 에서만 작동한다.)
(setq browse-kill-ring-no-duplicates t)
;; 중복되는 복사본 표시않함
(setq browse-kill-ring-display-duplicates nil)
;; 가장 최근 중복 복사본 표시
(setq browse-kill-ring-display-leftmost-duplicates t)
;; 최대 60글자만 표시
(setq browse-kill-ring-maximum-display-length 120)
;; 미리보기 표시
(setq browse-kill-ring-show-preview t)
;; 종료시 browse-kill-ring 창 닫기
(setq browse-kill-ring-quit-action 'save-and-restore)
;; 복사 목록 숫자 늘리기(디폴트 60개)
(setq kill-ring-max 200)
;; 속성은 제외하고 복사한다.(색상 등)
(setq browse-kill-ring-depropertize t)
(global-set-key [f7] 'browse-kill-ring)
;; =============================================================================
;; prog mode 설정하기(emacs 24+ only)
;; =============================================================================
(add-hook 'prog-mode-hook
(lambda ()
;; 들여쓰기 할 때 실제 탭문자 입력
(setq indent-tabs-mode t)
;; 탭 사이즈 4
(setq tab-width 4)
;; 대응하는 괄호 표시
(show-paren-mode t)
;; 엔터 입력시 들여쓰기
(local-set-key (kbd "RET") 'newline-and-indent)
))
;; =============================================================================
;; elisp
;; =============================================================================
(add-hook 'emacs-lisp-mode-hook
(lambda ()
(setq indent-tabs-mode nil)
(setq tab-width 2)))
;; =============================================================================
;; Web Mode
;; (필요 : MELPA, web-mode)
;; =============================================================================
(use-package web-mode
:ensure t)
(add-to-list 'auto-mode-alist '("\\.jsp\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.asp\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.php\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
(setq web-mode-engines-alist
'(("asp" . "\\.asp\\'")))
(setq web-mode-enable-auto-pairing nil)
(setq web-mode-script-padding 0)
(setq web-mode-style-padding 0)
;; (defun my-web-mode-hook ()
;; (setq web-mode-enable-auto-pairing nil)
;; (electric-indent-local-mode -1))
;; (add-hook 'web-mode-hook 'my-web-mode-hook)
;; =============================================================================
;; 커서 위치 대소문자 변환
;; =============================================================================
(defun my-upcase-char-or-region ()
"change char or selected region to upper case."
(interactive)
(if (region-active-p)
(progn
(upcase-region (region-beginning) (region-end))
(setq deactivate-mark nil))
(upcase-region (point) (+ (point) 1))))
(defun my-downcase-char-or-region ()
"change char or selected region to lower case."
(interactive)
(if (region-active-p)
(progn
(downcase-region (region-beginning) (region-end))
(setq deactivate-mark nil))
(downcase-region (point) (+ (point) 1))))
(global-set-key (kbd "<f5>") 'my-upcase-char-or-region)
(global-set-key (kbd "C-<f5>") 'my-downcase-char-or-region)
;; =============================================================================
;; zenburn-theme
;; (필요 : MELPA, zenburn-theme)
;; =============================================================================
(use-package zenburn-theme
:ensure t)
(load-theme 'zenburn t)
;; (set-face-background hl-line-face "#222222")
;; (set-face-attribute 'region nil :background "#4169e1")
(set-face-attribute 'region nil :background "#4169E1")
(set-face-attribute 'isearch nil :background "#4169E1")
;; (set-face-background 'hl-line "MidnightBlue")
;; ;;(setq curchg-input-method-cursor-color "Red")
;; ;; (setq curchg-default-cursor-color "Red")
;; ;; ;;(set-face-attribute 'region nil :background "#666")
;; ;; ;;(set-face-attribute 'region nil :background "#4169e1")
;; (set-face-attribute 'region nil :background "#4169e1")
;; (set-background-color "#000000")
;; (set-face-background hl-line-face "#222222")
;; ============================================================================
;; 윈도우 위치 & 사이즈 설정(GUI 버전)
;; ============================================================================
;; ;; 시작시 화면크기 최대로
;; (add-to-list 'default-frame-alist '(fullscreen . maximized))
;; 이맥스 프래임 최대화
(when (>= emacs-major-version 24)
(toggle-frame-maximized))
;; ============================================================================
;; 폰트에서 bold 를 모두 없앤다.
;; ============================================================================
(mapc
(lambda (face)
(when (eq (face-attribute face :weight) 'bold)
(set-face-attribute face nil :weight 'normal)))
(face-list))
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(cua-mode t nil (cua-base))
'(package-selected-packages '(use-package))
'(tool-bar-mode nil))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(default ((t (:family #("굴림체" 0 3 (charset cp949)) :foundry "outline" :slant normal :weight normal :height 90 :width normal)))))
Emacs 아이콘 생성하기
이맥스를 실행하면 도스창도 동시에 뜨기에, 도스창 없이 이맥스를 실행해 봅니다.
bin 폴더에 launch-emacs-client.vbs 라는 이름의 파일을 생성하고,
아래 내용을 입력합니다.
Set objShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
If WScript.Arguments.Count = 1 Then
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * From Win32_Process")
Dim isRunning
isRunning = False
For Each objItem in colItems
If InStr(objItem.CommandLine, "emacs.exe") Then
isRunning = True
End If
Next
If isRunning Then
objShell.Run(fso.GetParentFolderName(WScript.ScriptFullName) & "/emacsclientw.exe -n """ & WScript.Arguments(0) & """")
Else
objShell.Run(fso.GetParentFolderName(WScript.ScriptFullName) & "/runemacs.exe """ & WScript.Arguments(0) & """")
End If
Else
objShell.Run(fso.GetParentFolderName(WScript.ScriptFullName) & "/runemacs.exe")
End If
launch-emacs-client.vbs 를 실행하면 도스창없이 이맥스가 실행됩니다.
한영전환키 오류 수정하기
한영전환은 Shift-Space 로 전환할 수 있지만,
한영전환키는 이상하게 오작동합니다.
https://www.skyer9.pe.kr/wordpress/?p=5001 를 참조해서 오류를 수정할 수 있습니다.